본문 바로가기
백준 알고리즘/구현

인구 이동 C++

by paysmile 2021. 10. 19.

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

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모

www.acmicpc.net

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAX = 55;
int n, l, r;
int map[MAX][MAX];
int answer = 0;
int visited[MAX][MAX];
bool flag = false;
vector<pair<int, int>> v;
int sum = 0;
struct MOVE { int x, y; };
MOVE mv[4] = { {1,0}, {0,1}, {-1,0}, {0,-1} };
int tmp_m[MAX][MAX];

void dfs(int mi, int mj) {
	for (int k = 0; k < 4; k++) {
		int movei = mi + mv[k].x;
		int movej = mj + mv[k].y;

		if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
			if (find(v.begin(), v.end(), make_pair(movei, movej)) == v.end()) {
				int minus = abs(tmp_m[mi][mj] - tmp_m[movei][movej]);
				if (minus >= l && minus <= r) {
					v.push_back({ movei,movej });
					sum += tmp_m[movei][movej];
					dfs(movei, movej);
				}
			}
		}
	}
}

void copymap() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			tmp_m[i][j] = map[i][j];
		}
	}
}

int main(void) {
	cin >> n >> l >> r;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> map[i][j];
		}
	}

	while (true) {
		memset(visited, -1, sizeof(visited));
		flag = false;
		copymap();

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (visited[i][j] == -1) {
					v.clear();
					v.push_back({ i,j });
					sum = tmp_m[i][j];
					dfs(i, j);

					if (v.size() > 1) {
						flag = true;
						int value = int(sum / v.size());
						for (int k = 0; k < v.size(); k++) {
							map[v[k].first][v[k].second] = value;
							visited[v[k].first][v[k].second] = 1;
						}
					}
				}
			}
		}

		if (flag == false)	break;
		answer++;
	}
	cout << answer << endl;
}

 

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

드래곤 커브 C++  (0) 2021.10.21
인구 이동 C++  (0) 2021.10.21
나무 재테크 C++  (0) 2021.10.19
낚시왕 C++  (0) 2021.10.19
이차원 배열과 연산 C++  (0) 2021.10.19