득이공간

[백준 C++] 2667 단지번호붙이기 - 깊이우선탐색 본문

PS/알고리즘 문제풀이

[백준 C++] 2667 단지번호붙이기 - 깊이우선탐색

쟁득 2024. 1. 24. 11:01
 

2667번: 단지번호붙이기

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

www.acmicpc.net

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

int Complex = 0;
vector<int> Map;
vector<vector<int>> Neighbors;
vector<int> Households;

int NumberingComplex(int HouseIndex)
{
	int Count = 1;
	Map[HouseIndex] = Complex;

	for (int& Neighbor : Neighbors[HouseIndex])
	{
		if (Map[Neighbor] == 0)
		{
			Count += NumberingComplex(Neighbor);
		}
	}

	return Count;
}

int main()
{
	int n;
	cin >> n;

	Map.reserve(n * n);
	for (int i = 0; i < n * n; ++i)
	{
		char Character = cin.get();
		if (Character == '\n') Character = cin.get();
		Map.emplace_back(Character - '0' - 1);
	}

	Neighbors.reserve(n);
	for (int i = 0; i < n * n; ++i)
	{
		Neighbors.emplace_back(vector<int>());
	}

	int i = 0;
	for (const int& House : Map)
	{
		if (House == 0)
		{
			// top
			if (i / n > 0 && i - n >= 0
				&& Map[i - n] == 0)
			{
				Neighbors[i].emplace_back(i - n);
			}

			// bottom
			if (i / n < n - 1 && i + n < n * n
				&& Map[i + n] == 0)
			{
				Neighbors[i].emplace_back(i + n);
			}

			// left
			if (i % n > 0 && i - 1 >= 0
				&& Map[i - 1] == 0)
			{
				Neighbors[i].emplace_back(i - 1);
			}

			// right
			if (i % n < n - 1 && i + 1 < n * n
				&& Map[i + 1] == 0)
			{
				Neighbors[i].emplace_back(i + 1);
			}
		}

		++i;
	}

	i = 0;
	for (const int& House : Map)
	{
		if (House == 0)
		{
			++Complex;
			Households.emplace_back(NumberingComplex(i));
		}

		++i;
	}

	sort(Households.begin(), Households.end());

	cout << Complex << '\n';
	for (const int& Household : Households)
	{
		cout << Household << '\n';
	}
}

 

다음과 같은 순서로 진행되도록 코드를 작성했습니다.

 

1. 지도 정보 저장

2. 이웃 정보 저장

3. 단지 번호 붙이기 - 재귀함수 (DFS) & 단지별 세대수 저장

4. 단지별 세대수 정렬

5. 단지별 세대수 출력

 

이웃 정보 저장 단계에서 조건을 잘 설정해주는 것이 중요했습니다.