2 분 소요

인구 이동 (백준 Gold 4)

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

NxN개의 나라 정보가 주어질때
(각 나라는 1x1 크기)
인구 이동이 며칠 동안 발생하는지를 구하는 문제

조건들

  • 이웃나라들끼리 인구비교를 하였을때
    두 인구수의 차이가 L 이상 R 이하인 경우
    ‘국경’을 개방

  • 모든 나라들에 대하여 위에 대한 조건 판별 후
    국경이 개방된 나라들의 인구수가 평균이 된다
    (국경 개방 나라 인구수 / 국경 개방 나라 수)

  • 이후 국경을 폐쇄하고
    하루가 지나간다

풀이 방법

요점은 '인구 이동의 총 발생 일자'이며
조건이 맞지 않으면 그냥 바로 0일로 끝날수도 있다는 점이다

나는 BFS 탐색 방식을 사용하여 국경 개방 여부를 파악하였다

  • 해당 일자에 대한 Visit 배열을 사용하여
    방문 여부 검사
    (조건에 맞지 않으면, 애초에 그나라는 그날 국경 개방이 불가능함)

  • 두 인접 칸에서 인구수가 l이상 r 이하인지 검사
  • 동시에 국경을 개방한 나라들의 위치를 저장해둠
  • 저장한 위치들의 개수가 2개 이상이면 평균을 낸다

  • BFS가 성공하였다면, 하루가 흘러가고
    아니라면 종료하고 반환

제출 코드

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

int n, l, r;

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

bool bfs(vector<vector<int>>& maps, vector<vector<bool>>& visit, int y, int x)
{
	if (visit[y][x])
		return false;

	long sumValue = 0;
	vector<pair<int, int>> vecs;
	queue<pair<int, int>> q;

	q.push({ y,x });

	visit[y][x] = true;

	while (q.empty() == false)
	{
		int nowY = q.front().first;
		int nowX = q.front().second;
		q.pop();

		vecs.push_back({ nowY,nowX });
		sumValue += maps[nowY][nowX];

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

			if (ny < 0 || ny >= n ||
				nx < 0 || nx >= n)
				continue;

			if (visit[ny][nx])
				continue;

			int mV = abs(maps[nowY][nowX] - maps[ny][nx]);

			if (mV < l || mV > r)
				continue;

			visit[ny][nx] = true;
			q.push({ ny,nx });
		}
	}

	if (vecs.size() <= 1)
		return false;

	int v = sumValue / vecs.size();
	for (auto& p : vecs)
	{
		maps[p.first][p.second] = v;
	}

	return true;
}

int main()
{
	cin >> n >> l >> r;
	vector<vector<int>> maps(n, vector<int>(n, 0));

	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cin >> maps[i][j];
	int answer = 0;

	while (true)
	{
		bool dayNotChanged = true;

		vector<vector<bool>> visit(n, vector<bool>(n, false));

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if (visit[i][j] == false)
				{
					if (bfs(maps, visit, i, j))
					{
						dayNotChanged = false;
					}
				}
			}
		}
		if (dayNotChanged)
			break;

		answer++;
	}

	cout << answer;

	return 0;
}

결과

Image

일반적인 BFS 문제와는 살짝 달라 당황하였지만
문제를 침착하게 보니 풀 수 있었다

댓글남기기