알고리즘/시뮬레이션 & 구현

[백준/구현/C++] 16234번 인구 이동

데메즈 2023. 4. 25. 12:26
728x90
반응형

문제는 여기!

문제 해결 방법

1. 주변 나라끼리 인구수 차이가 L이상 R이하인 나라들을 체크한다

2. 체크한 나라중에 인접한 나라들을 구하고 인구를 나눈다(BFS) 사용

2번에서 인구수 차이를 한번 더 체크해야한다

#include <bits/stdc++.h>

using namespace std;
int N, L, R;
int A[51][51];
bool check[51][51], check2[51][51];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int year = 0;

void clear(){
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            check[i][j] = false;
            check2[i][j] = false;
        }
    }
}

void movePop(int a, int b){
    queue<pair<int, int>> nation, nation2;
    int cnt = 1, tot = A[a][b];
    nation.push({a, b});
    nation2.push({a, b});
    check2[a][b] = true;

    while(!nation.empty()){
        int x = nation.front().first;
        int y = nation.front().second;
        nation.pop();

        for(int i=0; i<4; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];

            if(nx<0 || nx>=N || ny<0 || ny>=N) continue;

            if(check[nx][ny] && !check2[nx][ny] && abs(A[nx][ny] - A[x][y])>=L && abs(A[nx][ny] - A[x][y])<=R){
                check2[nx][ny] = true;
                cnt++;
                tot += A[nx][ny];
                nation.push({nx, ny});
                nation2.push({nx, ny});
            }
        }
    }

    while(!nation2.empty()){
        int x = nation2.front().first;
        int y = nation2.front().second;
        nation2.pop();
        A[x][y] = tot/cnt;
    }
}

void checkPop(){
    bool flag = false;
    clear();

    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){

            for(int k=0; k<4; k++){
                int x = i + dx[k];
                int y = j + dy[k];

                if(x<0 || x>=N || y<0 || y>=N) continue;
                if(abs(A[i][j] - A[x][y])>=L && abs(A[i][j] - A[x][y])<=R && !check[i][j]){
                    check[i][j] = true;
                    flag = true;
                }
            }
        }
    }

    if(flag){
        year++;
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if(check[i][j] && !check2[i][j]){
                    movePop(i,j);
                }
            }
        }
        checkPop();
    } else return;
}

void input(){
    cin >> N >> L >> R;
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            cin >> A[i][j];
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    input();
    checkPop();
    cout << year;

    return 0;
}
728x90
반응형