2667
2667번: 단지번호붙이기
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여
www.acmicpc.net
문제
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.
입력
첫 번째 줄에는 지도의 크기 N(정사각형이므로 가로와 세로의 크기는 같으며 5≤N≤25)이 입력되고, 그 다음 N줄에는 각각 N개의 자료(0혹은 1)가 입력된다.
출력
첫 번째 줄에는 총 단지수를 출력하시오. 그리고 각 단지내 집의 수를 오름차순으로 정렬하여 한 줄에 하나씩 출력하시오.
코드
//2667 단지번호붙이기
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int house[26][26] = { 0, };
bool visited[26][26] = { 0, };
int N;
int nx[4] = { 1,0, -1, 0 }, ny[4] = { 0, 1, 0, -1 };
int num_complex = 0;
int num_house = 0;
void DFS(int x, int y) {
visited[x][y] = true;
num_house++;
for (int i = 0; i < 4; i++) {
int next_x = x + nx[i];
int next_y = y + ny[i];
if (next_x < 0 || next_y < 0 || next_x >= N || next_y >= N) {
continue;
}
if (house[next_x][next_y] == 1 && visited[next_x][next_y] == false) {
DFS(next_x, next_y);
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
string s;
for (int i = 0; i < N; i++) {
cin >> s;
for (int j = 0; j < N; j++) {
house[i][j] = s[j] - 48;
}
}
vector <int> v;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (house[i][j] != 0 && visited[i][j] == 0) {
num_complex++;
num_house = 0;
DFS(i, j);
v.push_back(num_house);
}
}
}
sort(v.begin(), v.end());
cout << num_complex << "\n";
for (int i = 0; i < v.size(); i++) {
cout << v[i] << "\n";
}
return 0;
}
설명
string으로 입력받아 하나씩 배열에 저장해준다. 이때 char형이므로 int형으로 변환하여 저장해줘야한다.
배열을 저장한 후 값이 1이고 방문하지 않은 위치에서 DFS 시작한다.
DFS를 시작할 때 단지가 시작되므로 num_complex를 증가시켜준다.
DFS를 시작한 노드부터 다음 노드를 방문할 때 마다 num_house를 증가시켜줘 단지 내에 집이 몇개 있는지를 확인하여 벡터에 단지 내 집의 수를 저장한다.
집을 모두 방문한 후 algorithm 헤더에 포함되어있는 sort함수를 이용하여 벡터를 오름차순으로 정렬한다.
따라서 단지수와 집의 수를 오름차순으로 정렬하여 출력할 수 있다.
결과
고찰
DFS로 단순하게 문제를 풀 수 있었다.
배열이면 nx[], ny[]를 더해줘 인접한 배열을 접근하면서 문제를 풀어야 한다.
난이도
●◐○○○
'알고리즘 > 백준' 카테고리의 다른 글
알고리즘(C++) / 백준 1697 : 숨바꼭질 (0) | 2021.05.16 |
---|---|
알고리즘(C++) / 백준 4963 : 섬의 개수 (0) | 2021.05.11 |
알고리즘(C++) / 백준 9466 : 텀 프로젝트 (0) | 2021.05.11 |
알고리즘(C++) / 백준 2331 : 반복수열 (0) | 2021.05.11 |
알고리즘(C++) / 백준 2745 : 진법 변환 (0) | 2021.05.09 |
댓글