알고리즘/백준

백준 16234 인구 이동

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

 

16234번: 인구 이동

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

www.acmicpc.net

유형: bfs, 시뮬레이션

  • 나라별로 구분 map을 구분 짓는다. bfs로 알 수 있음
  • bfs가 끝 났을 때 avg함수를 사용하여 map을 평균 값으로 업데이트 한다.
/*
	국경선을 번호로 구분한다
	type_sum[index]으로 구분
	type_num[index] 평균 구할 때 사용
	index가 의미하는건 국경선이다
	type에는 각 나라가 더한 값을 집어 넣는다.
	
	main
		입력
		완전탐색
			-1인경우만
				sol
		if flag
			avg
			flag=false
			유니온 -1로 초기화
	sol
		bfs사용
		while
			cur
			next
			if next union-1만,범위,차이값
				push
				union <- 유형별로 업데이트
				flag=true
	avg
		완탐
			유니온이 != -1
				type_sum[union[i][j]] += map[i][j]
				type_num[union[i][j]] ++;
		완탐
			map[i][j]=type_sum[유니온]/type_num[유니온]
*/
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int N, L, R;
int map[50][50];
int uni[50][50];
int dx[4] = { 0,0,1,-1 };
int dy[4] = { 1,-1,0,0 };
int flag = false;
int ans=0;

void sol(int y,int x,int ty)
{
	queue<pair<int, int>> q;
	q.push({ y,x });
	uni[y][x] = ty;
	while (!q.empty())
	{
		int cx = q.front().second;
		int cy = q.front().first;
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			int nx = cx + dx[i];
			int ny = cy + dy[i];
			if (0 <= nx && nx < N && 0 <= ny && ny < N && uni[ny][nx] == -1
				&& abs(map[ny][nx] - map[cy][cx]) >= L &&
				abs(map[ny][nx] - map[cy][cx]) <= R)
			{
				q.push({ ny,nx });
				uni[ny][nx] = ty;
				flag = true;
			}
		}
	}
}
void avg()
{
	vector<int> type_sum(2500);
	vector<int> type_num(2500);
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (uni[i][j] != -1)
			{
				type_sum[uni[i][j]] += map[i][j];
				type_num[uni[i][j]]++;
			}
		}
	}
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			map[i][j] = type_sum[uni[i][j]] / type_num[uni[i][j]];
		}
	}
}
int main() {
	cin >> N >> L >> R;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			cin >> map[i][j];
		}
	}
	memset(uni, -1, sizeof(uni));
	while (1)
	{
		int ty = 0;
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < N; j++)
			{
				if (uni[i][j] == -1)
				{
					sol(i, j, ty);
					ty++;
				}
			}
		}
		if (flag)
		{
			avg();
			flag = false;
			memset(uni, -1, sizeof(uni));
			ans++;
		}
		else
			break;
	}
	cout << ans;
}

'알고리즘 > 백준' 카테고리의 다른 글

[백준 10157] 자리배정  (0) 2020.09.20
[백준 1405] 미친 로봇  (0) 2020.08.15
백준 15686 치킨 배달  (0) 2020.03.13
백준 15685 드래곤 커브  (0) 2020.03.13
15684 사다리 조작  (0) 2020.03.13