1012번 유기농 배추
문제 해석
문제는 여러가지 방법으로 풀 수 있습니다.
문제는 간단히 말해 이렇답니다.
그냥 1이 뭉쳐저 있는 곳을 세는 겁니다.
단, 1은 상하좌우를 통해서 연결되어 집니다. 대각선으로 1은 서로 다른 지역으로 인식하게 되는 겁니다.
위의 예제에서는 1이 뭉쳐져 있는 곳이 총 5부분입니다. 그래서 답이 5가 되는 것입니다.
이런 문제는 조금 흔한 문제라서 딱 보면 그거네~ 하실 거에요.
제약 조건
테스트케이스 T가 주어지고 N과 M은 1이상 50 이하입니다. 배추가 심어져 있는 점은 Y, X로 주어집니다.
최대 50*50이 주어질 수가 있겠군요.
풀이
이 유기농배추가 있는 지도를 그래프로 생각을 해보도록 하겠습니다. 탐색 방법은 어떤 방향이든 좋습니다. 하지만 상하좌우 네 방향을 전부 탐색해야합니다. 단, 1인 정점만 탐색합니다.
현재 위치를 y,x라고 치고 상하좌우를 탐색합니다. 위쪽 정점은 현재 정점의 y-1, x 아래 정점은 현재 정점의 y+1,x, 왼쪽 정점은 현재 정점의 y, x-1, 오른쪽 정점은 현재 정점의 y, x+1입니다.
하지만 이미 방문되었다면 그 정점은 탐색하지 않습니다.
따라서 dfs가 몇번 호출되었는가가 이 문제의 답이됩니다. 코드를 통해서 살펴보도록 할까요?
#include <cstdio> #include <string.h> #define M 51 #define VISITED 0 using namespace std; int n, m, k; int map[M][M]; void dfs(int y, int x) { if ( y<0 || y >= n || x < 0 || x >= m || map[y][x] == VISITED ) return; map[y][x] = VISITED; dfs(y + 1, x); dfs(y, x + 1); dfs(y - 1, x); dfs(y, x - 1); } int main() { int T; scanf("%d",&T); for (int t = 0; t < T; t++) { memset(map, 0, sizeof(map)); scanf("%d %d %d", &m, &n, &k); for (int i = 0; i < k; i++) { int y, x; scanf("%d %d", &y, &x); map[x][y] = 1; } int count = 0; for (int y = 0; y < n; y++) { for (int x = 0; x < m; x++) if (map[y][x] == 1) { dfs(y, x); count++; } } printf("%d\n", count); } }
이중 for문을 돌며 1이 등장하면 그 정점부터 dfs를 실행합니다. dfs는 그 정점이 0이거나 y, x가 범위 밖이면 바로 return 됩니다.
그렇다면 우리는 그냥 0을 방문되었다고 표현하면 더 간단하게 문제를 풀 수 있지 않을까요?
아래 사진처럼 0,0에서 1을 만났다고 치겠습니다. 그렇다면 그 지점 0,0에서 dfs를 수행하면 앞뒤 양옆을 dfs로 순차적으로 돌아 전부 방문됩니다. 그러면 0으로 값이 변하게 되지요. 이 부분이 두번째 사진의 빨간색으로 된 0으로 표현을 했네요.
dfs가 끝났으니 for문을 계속 수행합니다. 하지만 이미 dfs가 돌아 0으로 값이 변했으므로 skip됩니다.
이런 식으로 dfs를 한번 돌게 되면 하나의 덩어리를 구할 수 있습니다. 이 덩어리의 수를 세는 것이 답입니다.
답은 위 코드의 count로 표현됩니다.
시간 복잡도는 N*M이 됩니다.
이외에도 BFS를 통해서도 문제의 해답을 구할 수도 있습니다.
마찬가지로 for문 속에서 일일이 루프를 돌면서 아직 방문되지 않는 점이 있으면 bfs를 돌고 count에 1을 더해 주기만 하면 되거든요.
BFS나 DFS나 둘 중 하나만 알아도 이 문제는 풀 수 있습니다.
또 어떤 방법으로 풀 수 있을까요??
'알고리즘 > DFS' 카테고리의 다른 글
[DFS] 위상정렬(Topological Sort)의 세부 설명 및 코드(C++) (0) | 2021.03.11 |
---|---|
[그래프] 이분 매칭(bipartite matching)의 설명과 코드, 예제 (0) | 2021.03.06 |
[알고리즘] 백준 온라인 저지 BOJ 2667 단지번호붙이기 풀이 및 코드 (0) | 2019.03.23 |
[알고리즘] 백준 온라인 저지 BOJ 1260 DFS와 BFS (0) | 2018.09.19 |
[알고리즘 : 그래프 이론] 그림으로 쉽게 보는 DFS 기본, 개념, 설명, 코드 (0) | 2018.09.12 |