https://www.acmicpc.net/problem/2667
2667번: 단지번호붙이기
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여
www.acmicpc.net
문제 이해
모든 경우를 탐색해서, 연결되어 있는 것들의 수를 세서 저장하면 된다. (map[i][j] == 0일때 BFS 혹은 DFS를 돌리기)
모든 경우를 탐색하기 때문에 DFS를 이용해도 되고, BFS를 이용해도 된다.
문제를 잘 읽어야하는게, 집의 개수를 저장한 배열을 정렬해서 출력해야 한다. (안했다가 계속 허탕침)
작성 코드(C)
1. BFS 이용
#include <stdio.h>
#include <stdlib.h>
int N;
int map[25 + 5][25 + 5];
int danji;
int house[25 * 25];
// 방향 벡터
int dx[] = { 0, 0, -1, 1 };
int dy[] = { -1, 1, 0, 0 };
// 큐
typedef struct pos {
int y;
int x;
}POS;
POS q[25 * 25 + 10];
int wp, rp;
void enq(int y, int x) {
q[wp].y = y;
q[wp].x = x;
wp++;
}
POS deq(void) {
POS tmp = q[rp];
rp++;
return tmp;
}
int empty(void) {
return wp == rp;
}
void BFS(int y, int x) {
wp = 0, rp = 0;
int cnt = 1;
map[y][x] = 0;
enq(y, x);
while (!empty()) {
POS cur = deq();
for (int i = 0; i < 4; i++) {
int ny = cur.y + dy[i];
int nx = cur.x + dx[i];
if (ny < 0 || ny >= N) continue;
if (nx < 0 || nx >= N) continue;
if (map[ny][nx] != 1) continue;
map[ny][nx] = 0;
enq(ny, nx);
cnt++;
}
}
house[danji] = cnt;
danji++;
}
int comp(const void* a, const void* b) {
int* p = (int*)a;
int* q = (int*)b;
return *p - *q;
}
int main(void) {
// 입력받기
scanf("%d", &N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%1d", &map[i][j]);
}
}
// BFS
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] == 1) BFS(i, j);
}
}
// output
qsort(house, danji, sizeof(house[0]), comp);
printf("%d\n", danji);
for (int i = 0; i < danji; i++) {
printf("%d\n", house[i]);
}
return 0;
}
2. DFS 이용
#include <stdio.h>
int N;
int map[25 + 5][25 + 5];
int cnt;
int ans_cnt = 0;
int ans[25 * 25 + 10];
int dx[] = { 0, 0, -1, 1 };
int dy[] = { -1, 1, 0, 0 };
void dfs(int y, int x) {
if (map[y][x] == 0) return;
map[y][x] = 0;
cnt++;
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
if (ny < 0 || nx < 0 || ny >= N || nx >= N) continue;
dfs(ny, nx);
}
}
int sort() {
for (int i = 0; i < ans_cnt; i++) {
for (int j = i+1; j < ans_cnt; j++) {
if (ans[i] > ans[j]) {
int t = ans[i];
ans[i] = ans[j];
ans[j] = t;
}
}
}
}
int main(void) {
scanf("%d", &N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%1d", &map[i][j]);
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] == 1) {
dfs(i, j);
ans[ans_cnt] = cnt;
ans_cnt++;
cnt = 0;
}
}
}
sort();
printf("%d\n", ans_cnt);
for (int i = 0; i < ans_cnt; i++) {
printf("%d\n", ans[i]);
}
return 0;
}
'컴퓨터기본 > 문제풀이' 카테고리의 다른 글
[SWEA] 2383. 점심 식사시간 (0) | 2021.10.09 |
---|---|
[백준] 2477번: 참외밭 (2) | 2021.09.26 |
[백준] 8983번: 사냥꾼 (0) | 2021.09.24 |
[정올] 1669번: 소시지 공장 (0) | 2021.09.24 |
[백준] 2479번: 경로 찾기 (0) | 2021.09.24 |