알고리즘/시뮬레이션
[백준] 16234-인구 이동(C++)
잉읭응
2020. 8. 12. 20:32
반응형
문제링크:https://www.acmicpc.net/problem/16234
16234번: 인구 이동
N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모��
www.acmicpc.net
시뮬레이션 문제입니다.
아래 조건들을 만족시키며 진행해야 합니다.
/*
국경선을 공유하는 두 나라의 인구 차이가 L명 이상, R명 이하라면, 두 나라가 공유하는 국경선을 오늘 하루동안 연다.
위의 조건에 의해 열어야하는 국경선이 모두 열렸다면, 인구 이동을 시작한다.
국경선이 열려있어 인접한 칸만을 이용해 이동할 수 있으면, 그 나라를 오늘 하루 동안은 연합이라고 한다.
연합을 이루고 있는 각 칸의 인구수는 (연합의 인구수) / (연합을 이루고 있는 칸의 개수)가 된다. 편의상 소수점은 버린다.
연합을 해체하고, 모든 국경선을 닫는다.
*/
알고리즘 입니다.
- 반복문을 통해서 각점들에서 dfs(혹은 bfs)를 통해서 인구이동이 가능한지 확인
- visited 사용(방문여부), sum(배열값 합), cnt 사용(배열 개수), vetor(방문 배열 좌표) - dfs(혹은 bfs)후에 변경된 값들을 arr에 저장, 이때 cnt는 2보다 크거나 같아야한다. bool값도 변경한다.
- bool값을 확인하고 반복문을 break할지 카운트값(result)을 올릴지 판단한다.
정답코드입니다.
#include <iostream>
#include <vector>
#include <cstring>
#include <math.h>
using namespace std;
int arr[51][51] = { 0 };
bool visited[51][51];
int n = 0, l = 0, r = 0;
int result = 0;
int cnt, sum;
vector <pair <int, int>> vec;
//dfs 방향
int y_ar[4] = { 1,-1,0,0 };
int x_ar[4] = { 0,0,1,-1 };
void dfs(int yy, int xx) {
for (int i = 0; i < 4; i++) {
int y = yy + y_ar[i];
int x = xx + x_ar[i];
if (!visited[y][x]) {
if (y >= 0 && y < n&&x >= 0 && x < n) {
if (abs(arr[yy][xx] - arr[y][x]) >= l && abs(arr[yy][xx] - arr[y][x]) <= r) {
visited[y][x] = 1;
cnt++;
sum += arr[y][x];
vec.push_back(make_pair(y, x));
dfs(y, x);
}
}
}
}
}
int main() {
cin >> n >> l >> r;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> arr[i][j];
while (1) {
bool jud = false;
memset(visited, 0, sizeof(visited));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!visited[i][j]) {
vec.clear();
cnt = 1;
sum = arr[i][j];
visited[i][j] = 1;
vec.push_back(make_pair(i,j));
dfs(i, j);
if (cnt >= 2) {
jud = true;
int aver_val = sum / cnt;
for (int k = 0; k < vec.size(); k++)
arr[vec.at(k).first][vec.at(k).second] = aver_val;
}
}
}
}
if (jud == false)
break;
else
result++;
}
cout << result << endl;
}
반응형