Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 코딩스킬
- 백트래킹
- priority_queue
- 삼성SW역량테스트
- dfs
- 시뮬레이션
- 브루트포스
- swea
- 이런게4문제
- find
- 백준
- 코딩테스트
- 모의SW역량테스트
- C++
- 2018
- KAKAO
- 레벨3
- Map
- dp
- 삼성SW테스트
- 완전탐색
- Sort
- 문자열
- Set
- substr
- 프로그래머스
- STL
- BFS
- 삼성
- 레벨2
Archives
- Today
- Total
-
[삼성SW테스트] 백준 17779번 - 게리맨더링 2 (정답률 58%) 본문
https://www.acmicpc.net/problem/17779
2019년 상반기 삼성 SW테스트 기출 문제다. (유형: 시뮬레이션 + BFS)
처음에 이 문제를 접하고 꽤 복잡한 조건이 있다고 생각했는데 좀 고민해보니 기준점의 범위와 d1, d2의 범위를 4중루프를 돌며 가능한 경우인지 먼저 검사하고, 순차적으로
1. 5의 테두리를 그리고
2. 1과 2, 3, 4의 경계선을 그어준 뒤,
3. 1, 2, 3, 4의 시작점을 각각 (1, 1), (1, N), (N, 1), (N, N)으로 잡아주어 BFS탐색으로 각 숫자로 초기화 해주고
4. 마지막으로 5의 면적을 초기화 해준뒤
5. 최종적으로 각 선거구의 넓이를 구해 최대 선거구와 최소 선거구의 차이가 최소가 되는 경우를 구하면 된다.
처음에 접하면 당황할 수 있는 문제지만 진득하게 조건을 꼼꼼히 따지고 정확하게 구현하면 1시간 내외로 풀 수 있는 문제같다.
아래는 소스코드 (76ms / 1s)
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 987654321
#define maxN 21
using namespace std;
typedef pair<int, int> pii;
vector<vector<pair<int, int> > > map, temp_map;
int N;
int answer = INF;
bool check[21][21];
typedef struct dir{
int dr, dc;
}dir;
dir direction[4] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
void reset(){
for (int i = 1; i <= N; i++){
for (int j = 1; j <= N; j++){
map[i][j] = temp_map[i][j];
check[i][j] = false;
}
}
}
bool possible(pii a, pii b, pii c, pii d){
if (a.first < 1 || a.first > N || a.second < 1 || a.second > N ||
b.first < 1 || b.first > N || b.second < 1 || b.second > N ||
c.first < 1 || c.first > N || c.second < 1 || c.second > N ||
d.first < 1 || d.first > N || d.second < 1 || d.second > N)
return false;
return true;
}
void make_1(){
pii first_1 = make_pair(1, 1);
queue<pii> q;
q.push(first_1);
check[1][1] = true;
while (!q.empty()){
int front_x = q.front().first;
int front_y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++){
int nr = front_x + direction[i].dr;
int nc = front_y + direction[i].dc;
if (nr >= 1 && nr <= N && nc >= 1 && nc <= N){
if (!check[nr][nc] && map[nr][nc].second == 0){
check[nr][nc] = true;
map[nr][nc].second = 1;
q.push(make_pair(nr, nc));
}
}
}
}
}
void make_2(){
pii first_2 = make_pair(1, N);
queue<pii> q;
q.push(first_2);
check[1][N] = true;
while (!q.empty()){
int front_x = q.front().first;
int front_y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++){
int nr = front_x + direction[i].dr;
int nc = front_y + direction[i].dc;
if (nr >= 1 && nr <= N && nc >= 1 && nc <= N){
if (!check[nr][nc] && map[nr][nc].second == 0){
check[nr][nc] = true;
map[nr][nc].second = 2;
q.push(make_pair(nr, nc));
}
}
}
}
}
void make_3(){
pii first_3 = make_pair(N, 1);
queue<pii> q;
q.push(first_3);
check[N][1] = true;
while (!q.empty()){
int front_x = q.front().first;
int front_y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++){
int nr = front_x + direction[i].dr;
int nc = front_y + direction[i].dc;
if (nr >= 1 && nr <= N && nc >= 1 && nc <= N){
if (!check[nr][nc] && map[nr][nc].second == 0){
check[nr][nc] = true;
map[nr][nc].second = 3;
q.push(make_pair(nr, nc));
}
}
}
}
}
void make_4(){
pii first_4 = make_pair(N, N);
queue<pii> q;
q.push(first_4);
check[N][N] = true;
while (!q.empty()){
int front_x = q.front().first;
int front_y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++){
int nr = front_x + direction[i].dr;
int nc = front_y + direction[i].dc;
if (nr >= 1 && nr <= N && nc >= 1 && nc <= N){
if (!check[nr][nc] && map[nr][nc].second == 0){
check[nr][nc] = true;
map[nr][nc].second = 4;
q.push(make_pair(nr, nc));
}
}
}
}
}
void make(pii left, pii right, pii std_point, pii bottom){
// 선 그어주고 체크.
}
}
}
}
}
}
}
}
// 5외곽선, 각 꼭지점 초기화 (1, 2, 3, 4), 구분선.
}
}
}
}
make_1();
make_2();
make_3();
make_4();
queue<pii> q;
q.push(start_5);
while (!q.empty()){
int front_x = q.front().first;
int front_y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++){
int nx = front_x + direction[i].dr;
int ny = front_y + direction[i].dc;
if (nx >= 1 && ny <= N && ny >= 1 && nx <= N){
if ((!check[nx][ny] && map[nx][ny].second == 0) ||
(!check[nx][ny] && map[nx][ny].second == 5)){
check[nx][ny] = true;
map[nx][ny].second = 5;
q.push(make_pair(nx, ny));
}
}
}
}
// 5 채우기 완료.
// 각 숫자 경계선 완료.
}
void calculation(){
int Sum[5] = { 0, 0, 0, 0, 0 };
for (int i = 1; i <= N; i++){
for (int j = 1; j <= N; j++){
int cur_category = map[i][j].second;
Sum[cur_category-1] += map[i][j].first;
}
}
int maximum = -1; int minimum = INF;
for (int i = 0; i < 5; i++){
maximum = max(maximum, Sum[i]);
minimum = min(minimum, Sum[i]);
}
answer = min(answer, abs(maximum - minimum));
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N;
for (int i = 1; i <= N; i++){
for (int j = 1; j <= N; j++){
int a;
cin >> a;
map[i][j].first = a;
map[i][j].second = 0;
temp_map[i][j].first = a;
temp_map[i][j].second = 0;
}
}
reset();
for (int x = 1; x <= N - 2; x++){
for (int y = 2; y <= N - 1; y++){
for (int d1 = 1; d1 <= maxN; d1++){
for (int d2 = 1; d2 <= maxN; d2++){
pii std_point = make_pair(x, y);
pii left = make_pair(x + d1, y - d1);
pii right = make_pair(x + d2, y + d2);
pii bottom = make_pair(x + d1 + d2, y + d2 - d1);
if (possible(std_point, left, right, bottom)){
make(left, right, std_point, bottom);
/*
cout << '\n';
cout << "x: " << x << " y: " << y << " d1: " << d1 << " d2: " << d2 << '\n';
cout << '\n';
for (int i = 1; i <= N; i++){
for (int j = 1; j <= N; j++){
cout << map[i][j].second << " ";
}
cout << '\n';
}
cout << '\n';
*/
calculation();
reset();
// 내부 점 하나 잡아서 bfs 탐색.
}
}
}
}
}
cout << answer << '\n';
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 |
'1-1. 삼성 SW 테스트' 카테고리의 다른 글
[삼성SW테스트] 백준 14890번 - 경사로 (정답률 52%) (0) | 2020.01.20 |
---|---|
[삼성SW테스트] 백준 17837번 - 새로운 게임 2 (정답률 46%) (0) | 2020.01.19 |
[삼성SW테스트] 백준 17822번 - 원판 돌리기 (정답률 31%) (0) | 2020.01.16 |
[삼성SW테스트] 백준 17825번 - 주사위 윷놀이 (정답률 30%) (0) | 2020.01.15 |
[삼성SW테스트] 백준 13460번 - 구슬 탈출 2 (정답률 24%) (0) | 2020.01.15 |
Comments