[백준 / C언어] 2667번: 단지번호붙이기

728x90
728x90

슬라이드1.JPG

https://www.acmicpc.net/problem/2667

 

2667번: 단지번호붙이기

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여

www.acmicpc.net

2667 1.png
2667 2.png

 

난이도: solved.ac 실버 1

 

 

사용 알고리즘

DFS (BFS도 가능)

 

 

 

접근 방법

DFS와 BFS 알고리즘 기본 문제다

먼저 for문을 이용해 한 칸씩 이동하며 집을 찾아주고, 집을 찾으면 해당 집이 속한 단지를 DFS를 이용해 찾아주었다

이때 집의 개수도 size라는 변수를 통해 세어주었다

그리고 한 단지의 탐색이 끝나면 num이라는 배열에 위에서 구한 size를 저장시켜주었다

이 과정을 반복하고 모든 단지의 탐색이 끝나면 qsort를 이용해 배열 num을 오름차순으로 정렬시켜주었다

 

여기서 num의 크기가 400인데, 이는 원래 최대 단지의 수가 313(13*13 + 12* 12)개지만 313이라는 숫자보다는 400이라는 숫자가 깔끔해보여서 넉넉하게 400으로 잡아준 것이다

 

그리고 DFS를 탐색하는 동안 배열 바깥 index로는 이동하지 못하게 배열의 index를 넘어가는 경우에는 DFS를 실행하지 않도록 해주었다

 

(코드)

#include<stdio.h>
#define MAX 26
int map[MAX][MAX];
int visited[MAX][MAX];
int num[400];
int size;
void DFS(int i, int j, int N);
int compare(int* a, int* b) {
return *a - *b;
}
int main() {
int N, i, j, cnt = 0;
scanf("%d", &N);
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
scanf("%1d", &map[i][j]);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (map[i][j] && !visited[i][j]) {
DFS(i, j, N);
num[cnt] = size;
cnt++;
size = 0;
}
}
}
qsort(num, cnt, sizeof(int), compare);
printf("%d\n", cnt);
for (i = 0; i < cnt; i++)
printf("%d\n", num[i]);
return 0;
}
void DFS(int i, int j, int N) {
visited[i][j] = 1;
size++;
if (i - 1 >= 0)
if(map[i - 1][j] && !visited[i - 1][j])
DFS(i - 1, j, N);
if (j - 1 >= 0)
if(map[i][j - 1] && !visited[i][j - 1])
DFS(i, j - 1, N);
if (map[i + 1][j] && !visited[i + 1][j])
DFS(i + 1, j, N);
if (map[i][j + 1] && !visited[i][j + 1])
DFS(i, j + 1, N);
}

 

반응형