[백준 2667번 C/C++] 단지 번호 붙이기

 

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

 

2667번: 단지번호붙이기

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

www.acmicpc.net


 

해결전략

 

Breadth First Search (BFS), 너비우선탐색


 

코드

 

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

int n, cnt; // n: 맵의 크기, cnt: 단지의 크기
vector<vector<int>> v, ch; // v: 입력받은 맵, ch: 방문 여부를 체크
vector<int> house; // 단지 크기 정보를 저장할 벡터
queue<pair<int, int>> Q; // BFS에서 사용할 큐

int dirY[4] = { -1, 0, 1, 0 }; 
int dirX[4] = { 0, -1, 0, 1 }; 


void BFS(int y, int x) // 시작점 y,x부터 탐색 시작
{
	cnt = 1; 
	Q.push({ y, x });
	ch[y][x] = 1;

	while (!Q.empty()) 
	{
		int y = Q.front().first;
		int x = Q.front().second;
		Q.pop();

		for (int i = 0; i < 4; i++) 
		{
			int ny = y + dirY[i];
			int nx = x + dirX[i];

			if (ny < 0 || n <= ny || nx < 0 || n <= nx || v[ny][nx] == 0) continue;

			if (ch[ny][nx] == 0)
			{
				ch[ny][nx] = 1;
				Q.push({ ny, nx });

				cnt++;
			}
		}
    }

    house.push_back(cnt); // 한 단지 탐색이 끝나면 그 크기(cnt)를 house 벡터에 추가
}


int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin >> n;
	v.resize(n,vector<int>(n));
	ch.resize(n,vector<int>(n));

	string input;
	for (int y=0;y<n;y++) {
        cin >> input;
        for(int x=0;x<n;x++) {
            v[y][x] = input[x] - '0';
        }
    }	

	for (int y=0;y<n;y++) {
		for(int x=0;x<n;x++) {
			if(v[y][x] == 1 && ch[y][x]==0) { // 아직 방문하지 않은 집이라면 BFS 시작
				BFS(y,x);
			}
		}
	}

	sort(house.begin(),house.end()); // 단지 크기를 오름차순으로 정렬.

	cout << house.size() << "\n"; 
	for(const auto& i : house) { 
		cout << i << "\n";
	}

	return 0;
}