Algorithm/백준

[백준][16234번] 인구 이동

1일1코딩 2020. 5. 2. 16:32

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

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다. 오늘부터 인구 이동이 시작되는 날이다. 인구 이동은 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다. 국경선을 공유하는 두 나라의 인구 차이가 L명

www.acmicpc.net

풀이과정

 

1. 인구이동이 일어나는 인전합 나라를 체크하기 위해 BFS를 사용했다.

 

2. visited배열을 통해 이미 방문한 나라는 또 방문하지 않는다.

 

3. 동시에 여러 구역에서 인구이동이 일어 날 수 있으므로, 모든 구역을 다 체크해야 한다.

 

소스코드

더보기
#include <stdio.h>
#include <string.h>
#include <queue>
#include <math.h>
using namespace std;
int map[50][50];
int visited[50][50];
int N, R, L;
int dx[4] = { 1, -1, 0, 0 };
int dy[4] = { 0, 0, 1, -1 };
int moving = 0;
bool checkOpen(int n1, int n2)
{
	int result = abs(n1 - n2);
	if (result >= L && result <= R) {
		return true;
	}
	return false;
}

void bfs(int x, int y)
{
	queue<pair<int, int>> que;
	vector<pair<int, int>> v;
	int sum = map[y][x];
	que.push(make_pair(x, y));
	v.push_back(make_pair(x, y));
	visited[y][x] = 1;
	while (!que.empty()) {
		int queSize = que.size();
		for (int i = 0; i < queSize; i++) {
			pair<int, int> p = que.front(); que.pop();
			for (int j = 0; j < 4; j++) {
				int nx = p.first + dx[j];
				int ny = p.second + dy[j];
				if (visited[ny][nx] == 0 && nx >= 0 && ny >= 0 && nx < N && ny < N) {
					if (checkOpen(map[p.second][p.first], map[ny][nx])) {
						visited[ny][nx] = 1;

						sum += map[ny][nx];
						pair<int, int> tmp = make_pair(nx, ny);
						que.push(tmp);
						v.push_back(tmp);
					}
				}
			}
		}
	}

	int result = sum / v.size();
	for (int i = 0; i < v.size(); i++) {
		map[v[i].second][v[i].first] = result;
	}
	if (v.size() > 1) {
		moving = 1;
	}
}

int solution()
{
	int answer = 0;
	while (1) {
		moving = 0;
		memset(visited, 0, sizeof(visited));
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (visited[i][j]) continue;
				bfs(j, i);
			}
		}
		if (!moving) {
			return answer;
		}
		answer++;
	}
}

int main()
{
	scanf("%d %d %d", &N, &L, &R);

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			scanf("%d", &map[i][j]);
		}
	}

	printf("%d\n", solution());
}

 

결과