-

[삼성SW테스트] 백준 16234번 - 인구 이동 본문

1-1. 삼성 SW 테스트

[삼성SW테스트] 백준 16234번 - 인구 이동

asdklfjlasdlfkj 2020. 1. 2. 23:27

삼성 SW역량 테스트 기출 문제이다. (유형: DFS 탐색)

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

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다. 오늘부터 인구 이동이 시작되는 날이다. 인구 이동은 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다. 국경선을 공유하는 두 나라의 인구 차이가 L명

www.acmicpc.net

1x1칸으로 나뉘어진 땅에 각 나라가 존재하며, 조건에 맞게 나라간 국경선이 열리거나 닫혀 인구 이동이 일어난다고 한다. 각 나라가 인접한 나라와 특정 값 범위내로 인구 차이가 있다면 국경선이 열리고, 최종적으로 연합을 한 국가들의 수로 이 국가들의 모든 인구를 나누어 동일한 인구를 가진 뒤에 국경선이 닫히는 과정을 반복한다. 문제는 인구이동이 몇 번 이루어 지는지를 묻고 있다.

 

이 문제는 DFS 탐색으로 쉽게 풀 수 있다. 모든 방문여부 배열을 false로 초기화 하고 <1, 1> 위치부터 탐색하지 않으면 깊이우선탐색을 해서 연합으로 끼워넣을 수 있는 나라들을 벡터에 모두 넣는다. 만약 두 개 이상의 나라가 연합했다면 아직 인구이동이 이루어지는 과정이기 때문에 이들의 평균 인구를 각 나라에 모두 넣고 계속해서 while을 돌린다. 만약 모든 나라를 탐색해서 두 개 이상의 나라가 연합하는 경우가 발생하지 않는다면 인구이동이 이루어지지 않게되므로 인구이동이 발생한 횟수를 출력하고 종료하면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX 51
using namespace std;
int N, L, R;
int A[MAX][MAX];
bool check[MAX][MAX];
int answer = 0;
bool quit = true;
int people, country_cnt;
vector<pair<intint> > v;
typedef struct dir{
    int dr, dc;
}dir;
dir direction[4= { { 01 }, { 0-1 }, { 10 }, { -10 } };
 
void falsing(){
    for (int i = 0; i < MAX; i++)
        for (int j = 0; j < MAX; j++)
            check[i][j] = false;
}
 
void DFS(int r, int c){
    for (int i = 0; i < 4; i++){
        int n_r = r + direction[i].dr;
        int n_c = c + direction[i].dc;
        if (n_r >= 1 && n_r <= N && n_c >= 1 && n_c <= N){
            // 1. 범위 내에 있고,
            if (!check[n_r][n_c]){
                // 2. 방문하지 않았으며,
                if (abs(A[r][c] - A[n_r][n_c]) >= L && abs(A[r][c] - A[n_r][n_c]) <= R){
                    // 3. 두 나라의 차이가 조건에 맞다면
                    v.push_back(make_pair(n_r, n_c));
                    check[n_r][n_c] = true;
                    people += A[n_r][n_c];
                    country_cnt++;
                    DFS(n_r, n_c);
                }
            }
        }
    }
}
 
int main(){
    ios_base::sync_with_stdio(0);
    cout.tie(0);
    cin.tie(0);
 
    cin >> N >> L >> R;
    for (int i = 1; i <= N; i++){
        for (int j = 1; j <= N; j++)
            cin >> A[i][j];
    }
 
    falsing();
    while (1){
        for (int r = 1; r <= N; r++){
            for (int c = 1; c <= N; c++){
                if (!check[r][c]){
                    check[r][c] = true;
                    v.push_back(make_pair(r, c));
                    people = A[r][c];
                    country_cnt = 1;
                    DFS(r, c);
                    if (country_cnt > 1){
                        for (int i = 0; i < v.size(); i++){
                            A[v[i].first][v[i].second] = people / country_cnt;
                        }
                        quit = false;
                    }
                    v.clear();
                }
            }
        }
 
        if (quit){
            cout << answer << '\n';
            break;
        }
        quit = true;
        falsing();
        answer++;
    }
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

Comments