알고리즘 풀이/백준(Boj)
백준(BOJ) 16234번 인구 이동
100win10
2019. 11. 22. 16:03
문제 : https://www.acmicpc.net/problem/16234
16234번: 인구 이동
N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다. 오늘부터 인구 이동이 시작되는 날이다. 인구 이동은 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다. 국경선을 공유하는 두 나라의 인구 차이가 L명
www.acmicpc.net
풀이 :
연합이 될 수있는 칸들을 BFS를 통해서 탐색한다. 연합이 자기 자신을 제외하고 하나라도 있다면
ans를 +1 해주고 계속해서 연합을 탐색하고 아니라면 바로 종료한다.
연합들을 만들었다면 값들을 모두 바꾸어 주어야 하는데 스택을 이용하여 BFS를 통해 방문한 좌표들을
담은 후 새로 구한 값으로 다 바꾸어주자.
코드( C ++ )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <algorithm> | |
#include <queue> | |
#include <stack> | |
#include <cstring> | |
using namespace std; | |
int n, l, r; | |
int a[50][50]; | |
int visited[50][50]; | |
const int dy[4] = { 1,-1,0,0 }; | |
const int dx[4] = { 0,0,1,-1 }; | |
bool bfs(int l, int r) | |
{ | |
memset(visited, 0, sizeof(visited)); | |
bool isTrue = false; | |
for (int i = 0; i < n; ++i) | |
for (int j = 0; j < n; ++j) | |
{ | |
if (visited[i][j]) continue; | |
queue<pair<int, int>> q; | |
q.push({ i,j }); | |
visited[i][j] = true; | |
//기록을 위한 스택 | |
stack<pair<int, int>> st; | |
st.push({ i,j }); | |
int sum = a[i][j]; | |
while (!q.empty()) | |
{ | |
int y = q.front().first; | |
int x = q.front().second; | |
q.pop(); | |
for (int k = 0; k < 4; ++k) | |
{ | |
int ny = y + dy[k]; | |
int nx = x + dx[k]; | |
if (!(0 <= ny && ny < n && 0 <= nx && nx < n)) continue; | |
if (visited[ny][nx]) continue; | |
int diff = abs(a[ny][nx] - a[y][x]); | |
if (l <= diff && diff <= r) | |
{ | |
q.push({ ny,nx }); | |
st.push({ ny,nx }); | |
visited[ny][nx] = true; | |
// 연합이 생겼다면 true | |
isTrue = true; | |
sum += a[ny][nx]; | |
} | |
} | |
} | |
int ret = sum / st.size(); | |
while (!st.empty()) | |
{ | |
int y = st.top().first; | |
int x = st.top().second; | |
st.pop(); | |
a[y][x] = ret; | |
} | |
} | |
return isTrue; | |
} | |
int main() | |
{ | |
cin >> n >> l >> r; | |
for (int i = 0; i < n; ++i) | |
for (int j = 0; j < n; ++j) | |
cin >> a[i][j]; | |
int ans = 0; | |
while (1) | |
{ | |
if (bfs(l, r)) | |
ans++; | |
else | |
break; | |
} | |
cout << ans << "\n"; | |
return 0; | |
} |
