알고리즘 문제풀이/BOJ
[BOJ] 삼성 sw 역량 테스트 기출 :: 17779번 게리맨더링 2 (java)
- -
BOJ 17779번 게리맨더링 2 문제 자바(java) 풀이
- 랭크 : 골드4
- 백준 17779번 게리맨더링 2
문제 정리
- 재현시의 크기 NxN
- 5개의 선거구로 나누어야 함
- 각 구역은 5개의 선거구 중 하나에 포함되어야 함
- 선거구는 적어도 구역 하나를 가져야 함
- 한 선거구에 포함되어 있는 구역은 모두 연결되어 있어야 함
- 인접한 구역을 통해 갈 수 있으면 연결되어 있다고 본다.
- 선거구에 있는 구역들은 모두 그 내에서 연결되어 있어야 한다.
- 인구가 가장 많은 선거구와 가장 적은 선거구의 인구 차이의 최솟값을 구해보자
문제 풀이
문제에서 주어진 대로 선거구를 정확히 나누기만 하면 쉬운 문제이다.
다만 처음에 0번 인덱스부터 했더니 헷갈려서 좀 걸렸다...
헤맸는데도 1시간 정도 걸린것 같다. 삼성 기출 중엔 쉬운 편인듯
디버깅 할때는 위 그림과 같은 상황을 맞추고 제대로 나누어지는지 확인하였다. (i=2, j=4, k=2, q=2)
1칸 더 잡고 1번 인덱스 부터 하니 에러는 없어졌다.
그리고 경계선 안쪽을 5번 선거구로 잘 표시하면 된다.
그리고 선거구 별로 모두 더하여 최대 인구와 최소 인구의 차이를 구하고 min 값을 update한다.
중요 표인트는 모든 경우를 검사하는데 그 때 x,y,d1,d2를 문제에 주어진 조건이 맞는지 먼저 확인하는게 중요한 것 같다.
백준 17779번 게리맨더링 2 java 코드
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
class Main {
static int[][] map;
static int N;
static int min;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N+1][N+1];
for(int i=1; i<=N; i++) {
String[] temp = br.readLine().split(" ");
for(int j=1; j<=N; j++) {
map[i][j] = Integer.parseInt(temp[j-1]);
}
}
min = Integer.MAX_VALUE;
// (x,y) 정하기
// d1, d2 정하기 길이는 1이상
// x + d1 + d2 <= N check
// 1 <= y-d1
// y+d2 <= N
for(int i=1; i<=N; i++) {
for(int j=1; j<=N; j++) {
for(int k=1; k<=N; k++) {
for(int q=1; q<=N; q++) {
if(i + k + q > N) continue;
if(1 > j - k) continue;
if(j + q > N) continue;
divide(i, j, k, q);
}
}
}
}
System.out.println(min);
}
public static void divide(int x, int y, int d1, int d2) {
int[][] check = new int[N+1][N+1];
// 경계선 나누기
for(int i=0; i<=d1; i++) {
check[x+i][y-i] = 5;
}
for(int i=0; i<=d2; i++) {
check[x+i][y+i] = 5;
}
for(int i=0; i<=d2; i++) {
check[x+d1+i][y-d1+i] = 5;
}
for(int i=0; i<=d1; i++) {
check[x+d2+i][y+d2-i] = 5;
}
// 경계선 안쪽
boolean start = false;
for(int i=x+1; i<x+d1+d2; i++) {
for(int j=1; j<=N; j++) {
if(start) {
// 오른쪽 경계선 도달
if(check[i][j] == 5) {
start = false;
break;
}
check[i][j] = 5;
}
// 왼쪽 경계선
if(check[i][j] == 5) {
start = true;
}
}
}
// 1번 선거구
for(int i=1; i<x+d1; i++) {
for(int j=1; j<=y; j++) {
if(check[i][j] == 5) continue;
check[i][j] = 1;
}
}
// 2번 선거구
for(int i=1; i<=x+d2; i++) {
for(int j=y+1; j<=N; j++) {
if(check[i][j] == 5) continue;
check[i][j] = 2;
}
}
// 3번 선거구
for(int i=x+d1; i<=N; i++) {
for(int j=1; j<y-d1+d2; j++) {
if(check[i][j] == 5) continue;
check[i][j] = 3;
}
}
// 4번 선거구
for(int i=x+d2+1; i<=N; i++) {
for(int j=y-d1+d2; j<=N; j++) {
if(check[i][j] == 5) continue;
check[i][j] = 4;
}
}
int diff = getDiffPopulation(check);
min = min > diff ? diff : min;
}
public static int getDiffPopulation(int[][] check) {
int[] sum = new int[5];
for(int i=1; i<=N; i++) {
for(int j=1; j<=N; j++) {
sum[check[i][j]-1] += map[i][j];
}
}
Arrays.sort(sum);
return sum[4] - sum[0];
}
}
|
cs |
'알고리즘 문제풀이 > BOJ' 카테고리의 다른 글
[BOJ] 삼성 sw 역량 테스트 기출 :: 17144번 미세먼지 안녕! (java) (0) | 2020.10.21 |
---|---|
[BOJ] 삼성 sw 역량 테스트 :: 17140번 이차원 배열과 연산 (java) (0) | 2020.10.19 |
[deque, 덱] 백준 1021번 회전하는 큐 c++ 풀이 (1) | 2020.07.03 |
[비트마스킹, set] 백준 11723번 집합 c++, java 풀이 (0) | 2020.06.30 |
[유니온 파인드, bfs] 백준 11724번 연결 요소의 개수 c++, java 풀이 (0) | 2020.06.28 |
Contents
소중한 공감 감사합니다