알고리즘과 자료구조/백준

BOJ 16234 인구 이동

bggbr 2020. 10. 20. 22:22

www.acmicpc.net/problem/16234

 

16234번: 인구 이동

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

www.acmicpc.net

문제 해결 전략

인구 이동을 할 때, check 배열로 이미 이동이 됐는지 체크하였다. 한 부분에서 인구 이동이 발생하면, 바로 sum과 cnt를 이용하여

평균값으로 대입해주었다. 이렇게 하지 않으면 한 구역(다수의 땅)에 다른 구역(다수의 땅)이 겹칠 수 있기 때문에 원치 않는 인구 이동이

발생할 수 있다.

 

소스

#include <iostream>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
#define endl "\n"
#define MAX 51
const int dy[] = {-1, 1, 0, 0};
const int dx[] = {0, 0, -1, 1};
int n, l, r;
int map[MAX][MAX];
bool check[MAX][MAX];
int totalNum;
int range(int temp1, int temp2) {
    if( abs(temp1 - temp2) >= l && abs(temp1 - temp2) <= r )
        return true;
    else
        return false;
}
void bfs(int yy, int xx) {
    int landSum = 0, landCnt = 0;
    queue<pair<int, int>> q;
    queue<pair<int, int>> nq;
    q.push({yy, xx});
    nq.push({yy, xx});
    check[yy][xx] = true;
    landSum += map[yy][xx];
    landCnt++;
    while(!q.empty()) {
        int y = q.front().first;
        int x = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++) {
            int ny = y + dy[i];
            int nx = x + dx[i];
            if(ny < 0 || ny >= n || nx < 0 || nx >= n) continue;
            if(!range(map[y][x], map[ny][nx]) || check[ny][nx]) continue;
            q.push({ny, nx});
            nq.push({ny, nx});
            check[ny][nx] = true;
            landSum += map[ny][nx];
            landCnt++;
        }
    }
    while(!nq.empty()) {
        int y = nq.front().first;
        int x = nq.front().second;
        nq.pop();
        map[y][x] = (landSum / landCnt);
    }
}
int main(int argc, char** argv) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n >> l >> r;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            cin >> map[i][j];
        }
    }
    while(1) {
        bool flag = true;
        memset(check, 0, sizeof(check));
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                for(int dir = 0; dir < 4; dir++) {
                    int ny = i + dy[dir];
                    int nx = j + dx[dir];
                    if(ny < 0 || ny >= n || nx < 0 || nx >= n || check[i][j]) continue;
                    if(!range(map[i][j], map[ny][nx])) continue;
                    bfs(i, j);
                    flag = false;
                }
            }
        }
        if(flag) break;
        totalNum++;
    }
    cout << totalNum;
}