큐를 활용한 BFS 풀이가 궁금하다면 아래 글을 참고하기 바란다.
https://hugssy.tistory.com/56?category=843457
평소 무의식적으로 bfs로만 풀이를 진행한 것 같아서, 이렇게 가끔 bfs로 풀이했던 문제들을 DFS로 풀이해보려고 한다.
확실히 코드가 간결해지긴 하는 것 같다. 무리 없이 재귀를 따라갈 수 있다면 쉽게 사용할 수 있을 것 같다.
일단 큐 따위를 사용하지 않기 때문에 pair 자료구조도 사용할 필요 없이 그냥 dfs 함수의 인자로는 row 값과 col 값을 담으면 되겠다.
방문한 적 없는 지점이면서 집이 있는 지점에서 최초로 dfs를 시작한다. 즉 main 함수에서 dfs를 실행시키는 것이, 새로운 단지를 찾았다는 것이 되겠다. 따라서 main 함수에서 dfs를 몇 번 수행하는지를 계산하면 단지의 전체 수를 찾을 수 있겠다.
필자는 이것을 벡터로 처리했다. 벡터를 사용하면 단지의 개수가 총 몇 개 나올 것인지 생각할 필요가 없기 때문에 좀 더 편하고 빠르게 문제를 풀 수 있다.
dfs 함수 내에서는, 범위 조건을 만족하고, 방문할 가치가 있는 곳이라면 이어서 dfs를 수행한다.
이어서 dfs를 실행할 상황이 온다는 것은, 곧 집을 하나 더 찾았다는 것을 의미한다.
이때 처음 dfs를 수행하기 시작한 곳도 집이라는 것을 생각해서 homeCnt를 1로 초기화해줘야 한다.
main 함수에서 한 번의 dfs가 모두 끝났다는 것은 단지 하나를 전부 돌았다는 것이다.
따라서 이 타이밍에 집의 개수를 추가해주고 다시 집의 개수를 초기화해주면 되겠다.
#pragma warning(disable :4996) #include<iostream> #include<algorithm> #include<vector> using namespace std; int n, m[26][26]; bool vis[26][26]; int dr[4] = { 0,0,1,-1 }; int dc[4] = { 1,-1,0,0 }; int homeCnt = 1; vector<int> v; void dfs(int row, int col) { vis[row][col] = true; for (int i = 0; i < 4; i++) { int nr = row + dr[i]; int nc = col + dc[i]; if (nr < 0 || nc < 0 || nr >= n || nc >= n) continue; if (vis[nr][nc] || m[nr][nc] == 0) continue; homeCnt++; dfs(nr, nc); } } int main(void) { cin >> n; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) scanf("%1d", &m[i][j]); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!vis[i][j] && m[i][j] == 1) { dfs(i, j); v.push_back(homeCnt); homeCnt = 1; } } } sort(v.begin(), v.end()); cout << v.size() << '\n'; for (int i = 0; i < v.size(); i++) cout << v[i] << '\n'; return 0; }
'알고리즘 문제 풀이 > 백준 온라인 저지' 카테고리의 다른 글
백준 7562번: 나이트의 이동 (C++) (0) | 2019.07.19 |
---|---|
백준 15656번: N과 M (7) (C++) (0) | 2019.07.18 |
백준 2667번: 단지번호붙이기 (C++) (0) | 2019.07.18 |
백준 9466번: 텀 프로젝트 (C++) (0) | 2019.07.18 |
백준 15655번: N과 M (6) (C++) (0) | 2019.07.17 |