BOJ 16234 :: 인구 이동
문제 링크 : https://www.acmicpc.net/problem/16234
나의 풀이
flag를 여러 군데에 사용하다 보니 코드가 좀 지저분한 감이 있긴 하다 ㅠㅠ
1. 배열을 방문하지 않았을 때, 너비 우선 탐색으로 인구 이동이 가능한 지역끼리 clustering을 한다.
2. 각 그룹은 숫자 1, 2, 3.. 으로 지정하고, 그에 맞는 인구 수를 계산하여 일차원 배열 group에 저장해 둔다.
3. 전체 배열의 탐색을 마치면, clustering 된 그룹의 인구 수를 미리 계산해 둔 group의 각 값으로 대체한다.
4. 탐색한 횟수를 증가시킨다.
5. 종료 조건 : 탐색 시, clustering이 한번도 되지 않았다면, flag가 변화하지 않아 종료.
나의 코드
Github : https://github.com/j2wooooo/Daliy_Algorithms/blob/master/Daliy_Algorithms/BOJ_16234/BOJ_16234.cpp
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 | // 백준알고리즘 16234번 :: 인구 이동 #include<iostream> #include<queue> using namespace std; int N, L, R, ans; bool flag = false; int A[51][51]; int visited[51][51]; int group[2502]; int dx[4] = { -1,1,0,0 }; int dy[4] = { 0,0,-1,1 }; queue<pair<int, int>> q; vector<int> v; // 국경선을 열고 연합하는 그룹만들기 void bfs(int _x, int _y, int _g) { visited[_x][_y] = _g; int sum = 0; int Nsum = 0; q.push(make_pair(_x, _y)); while (!q.empty()) { int qsz = q.size(); while (qsz--) { int x = q.front().first; int y = q.front().second; sum += A[x][y]; Nsum++; q.pop(); for (int i = 0; i < 4; i++) { int mx = x + dx[i]; int my = y + dy[i]; if (mx < 0 || mx >= N || my < 0 || my >= N) continue; if (visited[mx][my]) continue; if ((abs(A[x][y] - A[mx][my]) < L) || (abs(A[x][y] - A[mx][my]) > R)) continue; visited[mx][my] = _g; q.push(make_pair(mx, my)); flag = true; } } } // 국경선을 한 번이라도 열었을 때, 그룹을 만들고 대체할 값을 저장해둔다. if (flag) { int nvalue = sum / Nsum; group[_g] = nvalue; } // 국경선을 연 적이 없다면, 방문여부를 다시 표시한다. else visited[_x][_y] = 0; return; } int main(void) { cin >> N >> L >> R; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) cin >> A[i][j]; } while (1) { // 인구이동을 위한 탐색을 시작할 때, flag와 visited 배열을 초기화한다. flag = false; memset(visited, 0, sizeof(visited)); int g = 1; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (visited[i][j] == 0) { bfs(i, j, g); if(flag)g++; } } } // 인구 수가 갱신될 수 없으면 종료한다. if (!flag) break; // 그룹에 따른 인구수 갱신 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (visited[i][j]) A[i][j] = group[visited[i][j]]; } } // 모든 국가를 탐색하고 인구 수를 갱신한 후, 인구 이동 횟수를 증가시킨다. ans++; } cout << ans; return 0; } | cs |
'Problem > BFS' 카테고리의 다른 글
[C/C++] BOJ 16236 :: 아기 상어 (0) | 2019.03.08 |
---|---|
[C/C++] BOJ 3/2 코딩테스트 대비 모의고사 B번 - Baaaaaaaaaduk2 (Easy) (0) | 2019.03.02 |
[C/C++] BOJ 2234 :: 성곽 (0) | 2019.02.18 |
[C/C++] BOJ 1938 :: 통나무 옮기기 (0) | 2019.02.17 |
[C/C++] BOJ 1600 :: 말이 되고픈 원숭이 (0) | 2019.02.13 |