본문 바로가기

알고리즘/BOJ

16234. 인구 이동

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

 

16234번: 인구 이동

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

www.acmicpc.net

<JAVA>

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;

class Main {

	static final int dx[] = { 1, -1, 0, 0 };
	static final int dy[] = { 0, 0, 1, -1 };

	public static void main(String[] args) throws Exception {
		class pos {
			pos(int x, int y) {
				this.x = x;
				this.y = y;
			}

			int x, y;
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int N = Integer.parseInt(st.nextToken(" "));
		int L = Integer.parseInt(st.nextToken(" "));
		int R = Integer.parseInt(st.nextToken(" "));
		int cnt = 0, sum = 0;
		int map[][] = new int[N][N];
		boolean visit[][] = new boolean[N][N];
		List<pos> list = new ArrayList<>();
		Queue<pos> q = new LinkedList<>();
		for (int i = 0; i < N; ++i) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 0; j < N; ++j) {
				map[i][j] = Integer.parseInt(st.nextToken(" "));
			}
		}
		boolean isUpdate = true; // 인구 이동 여부 확인
		while (isUpdate) {
			isUpdate = false;
			visit = new boolean[N][N];
			// BFS
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N; ++j) {
					if (!visit[i][j]) {
						sum = 0;
						visit[i][j] = true;
						sum += map[i][j];
						q.add(new pos(i, j));
						list.add(new pos(i, j));
						while (!q.isEmpty()) {
							pos cur = q.poll();
							for (int dir = 0; dir < 4; ++dir) {
								int nx = cur.x + dx[dir];
								int ny = cur.y + dy[dir];
								if (nx < 0 || nx >= N || ny < 0 || ny >= N || visit[nx][ny]
										|| Math.abs(map[nx][ny] - map[cur.x][cur.y]) < L
										|| Math.abs(map[nx][ny] - map[cur.x][cur.y]) > R)
									continue;
								sum += map[nx][ny];
								visit[nx][ny] = true;
								q.add(new pos(nx, ny));
								list.add(new pos(nx, ny));
								isUpdate = true;
							}
						}
						sum /= list.size();
						for (int k = 0; k < list.size(); ++k) {
							map[list.get(k).x][list.get(k).y] = sum;
						}
						list.clear();
					}
				}
			}
			if (isUpdate) {
				++cnt;
			}
		}
		System.out.println(cnt);
	}
}

<C++>

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int dx[] = { 1, -1, 0, 0 };
const int dy[] = { 0, 0, 1, -1 };

int map[50][50];
bool visit[50][50];
int N, L, R, cnt, sum;
struct pos
{
	int x, y;
};
vector<pos> v;
queue <pos> q;
int main()
{
	cin.tie(NULL); cout.tie(NULL); ios_base::sync_with_stdio(false);
	cin >> N >> L >> R;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			cin >> map[i][j];
		}
	}

	bool isUpdate = true;	// 인구 이동 여부 확인
	while (isUpdate)
	{
		isUpdate = false;
		memset(visit, false, sizeof(visit));
		// BFS
		for (int i = 0; i < N; ++i)
		{
			for (int j = 0; j < N; ++j)
			{
				if (!visit[i][j])
				{
					sum = 0;
					visit[i][j] = true;
					sum += map[i][j];
					q.push({ i,j });
					v.push_back({ i,j });
					while (!q.empty())
					{
						pos cur = q.front(); q.pop();
						for (int dir = 0; dir < 4; ++dir)
						{
							int nx = cur.x + dx[dir];
							int ny = cur.y + dy[dir];
							if (nx < 0 || nx >= N || ny < 0 || ny >= N || visit[nx][ny] || abs(map[nx][ny] - map[cur.x][cur.y]) < L || abs(map[nx][ny] - map[cur.x][cur.y]) > R)
								continue;
							sum += map[nx][ny];
							visit[nx][ny] = true;
							q.push({ nx,ny });
							v.push_back({ nx,ny });
							isUpdate = true;
						}
					}
					sum /= v.size();
					for (int k = 0; k < v.size(); ++k)
					{
						map[v[k].x][v[k].y] = sum;
					}
					v.clear();
				}
			}
		}
		if (isUpdate)
		{
			++cnt;
		}
	}
	cout << cnt;
	return 0;
}

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

11509번 - 풍선 맞추기  (0) 2021.01.04
17472. 다리 만들기 2  (0) 2019.10.16
2644. 촌수계산  (0) 2019.10.15
10026. 적록색약  (0) 2019.10.15
14889. 스타트와 링크  (0) 2019.10.15