BOJ
BOJ 2573 빙산
bsgreentea
2018. 11. 17. 19:04
N과 M이 최대 300까지 가능하기 때문에, 이차원 배열의 크기는 최대 90000이다.
매번 배열의 모든 값을 탐색해주는 방식이라면, 최악의 경우 연산이 1억번이 넘어 1초의 제한시간이 부족할 수 있다.(뇌피셜임) 빙산의 개수가 최대 10000개이므로 빙산의 위치만 따로 관리해준다면 조금 더 빠른 시간에 문제를 해결할 수 있다.
빙산의 높이가 0이 된다면 인접한 빙산의 높이 변화에 영향을 줄 수 있기 때문에, 높이 변화를 temp라는 배열에 저장해준 이후에 빙산의 높이를 갱신해주는 방식으로 해결했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <cstdio> #include <cstring> #include <vector> using namespace std; // tot == 빙산 높이의 합 int n, m, tot; int map[303][303], visited[303][303]; vector<pair<int, int>> ice; // 1년마다 각 빙산이 얼마나 낮아지는지를 저장 // 1년(루프1 회)마다 초기화 int temp[10001]; // 4방 탐색 int dx[] = { 0,0,1,-1 }; int dy[] = { 1,-1,0,0 }; // 빙산에 접한 0의 개수를 세는 함수 int sea_cnt(int x, int y) { int cnt = 0; for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (map[nx][ny] == 0) cnt++; } return cnt; } // 빙산의 덩어리를 세기 위한 dfs void dfs(int x, int y) { visited[x][y] = 1; for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (!map[nx][ny] || visited[nx][ny]) continue; dfs(nx, ny); } } int main() { scanf("%d %d", &n, &m); int num; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf("%d", &num); if (num) { tot += num; map[i][j] = num; // 빙산이 있는 지점을 저장해준다 ice.push_back({ i,j }); } } } int flag = 0, res = 0; // 모든 빙산이 녹으면 멈춘다 while (tot) { memset(temp, 0, sizeof(temp)); int hx, hy; for (int i = 0; i < ice.size(); i++) { hx = ice[i].first; hy = ice[i].second; if (map[hx][hy]) temp[i] = sea_cnt(hx, hy); } int tmp; for (int i = 0; i < ice.size(); i++) { hx = ice[i].first; hy = ice[i].second; if (!temp[i]) continue; if (map[hx][hy]) { tmp = map[hx][hy] < temp[i] ? map[hx][hy] : temp[i]; tot -= tmp; map[hx][hy] -= tmp; } } memset(visited, 0, sizeof(visited)); // 빙산 덩어리의 수를 센다 int ices = 0; for (int i = 0; i < ice.size(); i++) { hx = ice[i].first; hy = ice[i].second; if (map[hx][hy] == 0) continue; if (!visited[hx][hy]) { dfs(hx, hy); ices++; } if (ices >= 2) { flag = 1; break; } } res++; if (flag) break; } if (flag) printf("%d\n", res); else puts("0"); } | cs |