반응형
처음엔 복잡하게 구현했었다.
테스트케이스는 모두 맞길래, 제출했었는데 컴파일 에러가 발생했다.
아무리 봐도 알고리즘이 복잡하다는 생각을 하고는 있었기에,, 풀이 방법을 참고해봤고
내 알고리즘에서 생략할 수 있는 부분이 많이 있단 것을 깨닫고 수정했다.
이 문제는, 전체 치킨 지역 중에서 조합으로 치킨집을 M개 뽑은 뒤에
집 별로 거리계산을 하기만 해주면 되는 문제였다.
변경 전 처음 코드 (틀림)
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int MAP[50][50];
bool CHECK[50][50];
int DEPTH[50][50];
int N, M;
vector<pair<int, int>> HOME; // x, y
vector<int> CHICKEN; // x * N + y
vector<pair<int, int>> HOME_INFO[50]; // 치킨위치, 거리
vector<int> SELECT_CHICKEN; // 치킨집 뽑기
int TOTAL_DISTANCE = 50 * 50 * 50;
int mx[4] = {0, 0, 1, -1};
int my[4] = {1, -1, 0, 0};
void bfs(int x, int y, int index) {
queue<pair<int, int>> que;
CHECK[x][y] = true;
que.push({x, y});
while(!que.empty()) {
int xx = que.front().first;
int yy = que.front().second;
que.pop();
for(int i = 0; i < 4; i++) {
int tx = xx + mx[i];
int ty = yy + my[i];
if(tx < 0 || tx >= N || ty < 0 || ty >= N)
continue;
if(!CHECK[tx][ty]) {
CHECK[tx][ty] = true;
DEPTH[tx][ty] = DEPTH[xx][yy] + 1;
que.push({tx, ty});
if(MAP[tx][ty] == 2) {
int coordi = tx * N + ty;
int distan = DEPTH[tx][ty];
HOME_INFO[index].push_back({coordi, distan});
}
}
}
}
}
void EVALUATE() {
int H_S = HOME.size();
int C_S = CHICKEN.size();
int S_C_S = SELECT_CHICKEN.size();
bool flag = false;
int DISTANCE = 0;
for(int i = 0; i < H_S; i++) {
for(int j = 0; j < C_S; j++) {
flag = false;
for(int k = 0; k < S_C_S; k++) {
if(HOME_INFO[i][j].first == SELECT_CHICKEN[k]) {
flag = true;
DISTANCE += HOME_INFO[i][j].second;
break;
}
}
if(flag)
break;
}
}
if(TOTAL_DISTANCE > DISTANCE)
TOTAL_DISTANCE = DISTANCE;
}
void dfs(int count) {
if(count == M ) {
EVALUATE();
return;
}
int C_S = CHICKEN.size();
for(int i = count; i < C_S; i++) {
SELECT_CHICKEN.push_back(CHICKEN[i]);
dfs(count + 1);
SELECT_CHICKEN.pop_back();
}
}
int main() {
cin >> N >> M;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
cin >> MAP[i][j];
if(MAP[i][j] == 1)
HOME.push_back({i, j});
else if(MAP[i][j] == 2)
CHICKEN.push_back((i * N) + j);
}
}
int H_S = HOME.size();
for(int i = 0; i < H_S; i++) {
memset(CHECK, 0, sizeof(CHECK));
memset(DEPTH, 0, sizeof(DEPTH));
bfs(HOME[i].first, HOME[i].second, i);
}
dfs(0);
cout << TOTAL_DISTANCE << "\n";
}
변경 후
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int MAP[50][50];
int N, M;
vector<pair<int, int>> HOME; // x, y
vector<pair<int, int>> CHICKEN; // x, y
vector<pair<int, int>> SELECT_CHICKEN; // x, y
int TOTAL_DISTANCE = 50 * 50 * 50;
void EVALUATE() {
int H_S = HOME.size();
int S_C_S = SELECT_CHICKEN.size();
int DISTANCE = 0;
for(int i = 0; i < H_S; i++) {
int MIN = 50 * 50;
for(int j = 0; j < S_C_S; j++) {
int val = abs(HOME[i].first - SELECT_CHICKEN[j].first) + abs(HOME[i].second - SELECT_CHICKEN[j].second);
if(MIN > val)
MIN = val;
}
DISTANCE += MIN;
}
if(TOTAL_DISTANCE > DISTANCE)
TOTAL_DISTANCE = DISTANCE;
}
void dfs(int index, int count) {
if(count == M ) {
EVALUATE();
return;
}
int C_S = CHICKEN.size();
for(int i = index; i < C_S; i++) {
SELECT_CHICKEN.push_back(CHICKEN[i]);
dfs(i + 1, count + 1);
SELECT_CHICKEN.pop_back();
}
}
int main() {
cin >> N >> M;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
cin >> MAP[i][j];
if(MAP[i][j] == 1)
HOME.push_back({i, j});
else if(MAP[i][j] == 2)
CHICKEN.push_back({i, j});
}
}
dfs(0, 0);
cout << TOTAL_DISTANCE << "\n";
}
너무 복잡하게, 어렵게 생각했었다.
소요 시간 : 1시간 30분
반응형
'[백준]' 카테고리의 다른 글
[BaekJoon/백준] 14500번 테트로미노 (0) | 2022.07.14 |
---|---|
[BaekJoon/백준] 16234번 인구 이동 (0) | 2022.07.13 |
[BaekJoon/백준] 3967번 매직 스타 (0) | 2022.07.11 |
[BaekJoon/백준] 2589번 보물섬 (0) | 2022.07.10 |
[BaekJoon/백준] 7569번 토마토 (0) | 2022.07.09 |