지도를 배열에 저장하고 칸별로 분기를 돌며 집이 있는 칸을 만나면 인접한 집들을 탐색한다. 위 과정을 반복해 단지를 나누고 집의 수를 벡터에 저장한 후 정렬해 출력한다. bfs dfs 두 방법 모두 다뤄보겠다.
두 방법 모두 한번 탐색한 집은 배열에서 삭제하므로 다음 분기에서 중복탐색하지 않는다. 덕분에 bfs에서 삭제 횟수가 해당 단지의 집 수가 된다.
bfs는 처음으로 집을 발견한 위치를 기준으로 상하좌우를 탐색하며 큐에 넣는다. 탐색하며 삭제한 집의 갯수가 곧 단지내의 집 수이기 때문에 그 값을 리턴한다. 리턴된 값을 벡터에 넣고 정렬 후 출력한다.
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 #include <iostream> #include <queue> #include <vector> #include <algorithm> using namespace std ;int n, v[27 ][27 ], sx, sy, sc, cnt;queue <int > qx, qy;vector <int > ans;int bfs (int x, int y) { cnt = 0 ; qx.push(x), qy.push(y); while (!(qx.empty() && qy.empty())) { sx = qx.front(); qx.pop(); sy = qy.front(); qy.pop(); if (!v[sy][sx]) continue ; v[sy][sx] = 0 ; cnt++; if (v[sy - 1 ][sx]) qx.push(sx), qy.push(sy - 1 ); if (v[sy + 1 ][sx]) qx.push(sx), qy.push(sy + 1 ); if (v[sy][sx - 1 ]) qx.push(sx - 1 ), qy.push(sy); if (v[sy][sx + 1 ]) qx.push(sx + 1 ), qy.push(sy); } return cnt; } int main () { cin >> n; for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= n; j++) scanf ("%1d" , &v[i][j]); for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= n; j++) if (v[i][j]) ans.push_back(bfs(j, i)); cout << ans.size() << endl ; sort(ans.begin(), ans.end()); for (int i = 0 ; i < ans.size(); i++) cout << ans[i] << endl ; }
dfs를 사용한 방법도 마찬가지로 지도 전체를 돌며 집을 발견한 위치를 시작점으로 탐색을 수행한다. 상하좌우 더 이상 이동할 공간이 없을때까지 재귀적으로 탐색하고 1씩 더해나간다. 최종적으로 dfs 탐색과정을 트리를 그리면 최하단 노드에는 1이 담기고 각 부모노드에는 자식노드 들의 합이 담겨있는 형태가 될 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <vector> #include <algorithm> using namespace std ;int n, arr[27 ][27 ];vector <int > ans;int dfs (int x, int y) { if (!arr[y][x]) return 0 ; arr[y][x] = 0 ; return dfs(x - 1 , y) + dfs(x + 1 , y) + dfs(x, y - 1 ) + dfs(x, y + 1 ) + 1 ; } int main () { cin >> n; for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= n; j++) scanf ("%1d" , &arr[i][j]); for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= n; j++) if (arr[i][j]) ans.push_back(dfs(j, i)); cout << ans.size() << endl ; sort(ans.begin(), ans.end()); for (int i = 0 ; i < ans.size(); i++) cout << ans[i] << endl ; }