백준의 인구이동(16234) 문제이다.

( 문제 바로가기 )


삼성전자 코딩테스트 기출문제이다..


[ 문제풀이 ]

1. 문제를 보면, BFS로 쉽게 해결할 수 있을 것 같지만 한 단계를 더 생각해 줘야 해결할 수 있는 문제이다.

   전체적인 풀이과정을 알아보자.

   1. 인구의 이동이 없을 때 까지 반복을 시켜준다.

      → 인구의 이동이 있었는지 없었는지 Check할 수 있는 변수가 필요하다.

   2. 인구 이동이 가능한 범위 내에 있는 값들에 대해서만 BFS를 통해서 인구이동을 시켜준다.

      → 인구 이동이 가능한 범위 내에 있는지 판별할 수 있는 함수가 필요하다.

   3. BFS내에서, 인구의 이동이 있었던 정점들만 따로 관리 및 표시 해주고, 값을 바꿔줘야 한다.

      → 인구 이동이 있었던 정점들만 따로 표시를 하던지, 저장을 해줘야 한다.


   < 풀이과정 1번 >

   본인은 Check라는 bool형 변수를 사용해서, 인구 이동이 있었으면 true로 표시, 없었으면 false로 표시하면서

   반복문을 관리해 주었다.

  

   < 풀이과정 2번 >

   본인은, 모든 정점에 대해서 탐색하면서,

   1. 아직 인구이동이 없었던 정점

   2. 해당 정점을 기준으로 상하좌우 값을 비교해서 인구이동이 일어날 수 있는 정점

   이 2가지 조건이 성립하면 BFS()를 호출하도록 구현해 주었다.

  

   < 풀이과정 3번 >

   BFS()함수 내에서, 인구 이동이 있었던 정점들의 값들은 바뀌어야 하므로, 이 정점들만 따로 관리할 수 있어야 한다.

   여러가지 방법이 있겠지만, 본인은 Queue를 하나 더 사용하였다.

   인구 이동이 일어날 수 있는 정점들에 대해서는 Queue에 저장해 주었고(본문 코드에서 Nq), BFS가 모두 진행된 후에

   따로 저장해둔 인구 이동이 일어날 수 있는 정점들에 대해서만 값을 모두 바꿔주었다.

   이 외에도, Visit배열의 값을 통해서 인구 이동이 일어난 정점인지 아닌지 판단할 수 있는 방법이 있을 것이다.


   문제 자체가 그리 어렵지는 않은데, 한 단계 더 응용할수 있어야 하는 문제인 것 같다.


[ 소스코드 ]

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
 
#define endl "\n"
#define MAX 50
using namespace std;
 
int N, L, R;
int MAP[MAX][MAX];
int Visit[MAX][MAX];
int Country_Number;
 
int dx[] = { 001-1 };
int dy[] = { 1-100 };
bool Check = true;
 
void Input()
{
    cin >> N >> L >> R;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cin >> MAP[i][j];
        }
    }
}
 
bool Can_Combination2(int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx >= 0 && ny >= 0 && nx < N && ny < N)
        {
            if (L <= abs(MAP[x][y] - MAP[nx][ny]) && abs(MAP[x][y] - MAP[nx][ny]) <= R) return true;
        }
    }
    return false;
 
bool Can_Combination(int x, int y, int xx, int yy)
{
    if (L <= abs(MAP[x][y] - MAP[xx][yy]) && abs(MAP[x][y] - MAP[xx][yy]) <= R) return true;
    return false;
}
 
void BFS(int a, int b)
{
    queue<pair<intint>> Q, Nq;
    Q.push(make_pair(a, b));
    Nq.push(make_pair(a, b));
    Visit[a][b] = true;
    int Sum = 0;
    int Cnt = 0;
 
    while (Q.empty() == 0)
    {
        int x = Q.front().first;
        int y = Q.front().second;
        Q.pop();
 
        Sum = Sum + MAP[x][y];
        Cnt = Cnt + 1;                                           
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
            if (Visit[nx][ny] != 0continue;
            if (Can_Combination(x, y, nx, ny) == true)
            {
                Visit[nx][ny] = 1;
                Q.push(make_pair(nx, ny));
                Nq.push(make_pair(nx, ny));
            }
        }
    }
 
    int Value = Sum / Cnt;
    
    while (Nq.empty() == 0)
    {
        int x = Nq.front().first;
        int y = Nq.front().second;
        Nq.pop();
        MAP[x][y] = Value;
    }
}
 
void Print()
{
    cout << "########################################" << endl;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            if (Visit[i][j] == 0)
            {
                cout << 0 << " ";
            }
            else
            {
                cout << Visit[i][j] << " ";
            }
        }
 
        cout << "\t\t";
        for (int j = 0; j < N; j++)
        {
            cout << MAP[i][j] << " ";
        }
        cout << endl;
    }
    cout << "########################################" << endl;
 
}
 
void Solution()
{
    int Day = 0;
    while (Check)
    {
        //Print();
        Check = false;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {                    
                if (Visit[i][j] == 0 && Can_Combination2(i,j) == true)
                {
                    BFS(i, j);
                    Check = true;
                }
            }
        }        
        if (Check == true) Day++;
        memset(Visit, falsesizeof(Visit));
 
    }
    cout << Day << endl;
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
//    freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
 
 
cs


'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글

[ 백준 2309 ] 일곱 난쟁이 (C++)  (0) 2019.01.11
[ 백준 1547 ] 공 (C++)  (0) 2019.01.11
[ 백준 1261 ] 알고스팟 (C++)  (3) 2019.01.11
[ 백준 1525 ] 퍼즐 (C++)  (2) 2019.01.11
[ 백준 14226 ] 이모티콘 (C++)  (0) 2019.01.11

+ Recent posts