https://www.acmicpc.net/problem/17779
17779번: 게리맨더링 2
재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름
www.acmicpc.net
[ 문제풀이 ]
1. 5구역을 정합니다.
2. 1-4구역을 규칙에 따라 나눕니다.
3. 각 구역의 인구를 구해 최댓값과 최솟값의 차를 구합니다.
4. 차의 최솟값을 ans에 저장합니다.
[ 소스코드 ]
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 | #include<iostream> #include<cstring> #include<queue> #include<algorithm> using namespace std; int N; int arr[20][20]; int temp[20][20]; int d[2]; int y, x; int dy[4] = { -1,1,0,0 }; int dx[4] = { 0,0,-1,1 }; int population; int ans = 987654321; int bfs(int num) //1 ~ 4구역 표시 { queue<pair<int, int>> q; int cury, curx; if (num == 1) { cury = 0; curx = 0; } else if (num == 2) { curx = N - 1; cury = 0; } else if (num == 3) { curx = 0; cury = N - 1; } else { curx = N - 1; cury = N - 1; } int ret = arr[cury][curx]; temp[cury][curx] = num; q.push({ cury,curx }); while (!q.empty()) { int curY = q.front().first; int curX = q.front().second; q.pop(); for (int i = 0; i < 4; i++) { int yy = curY + dy[i]; int xx = curX + dx[i]; if (yy >= 0 && yy < N && xx >= 0 && xx < N) { if (temp[yy][xx] == 0) { if (num == 1) { if (yy >= 0 && yy < y && xx >= 0 && xx <= x + d[0]) { temp[yy][xx] = 1; ret += arr[yy][xx]; q.push({ yy,xx }); } } else if (num == 2) { if (yy >= 0 && yy <= y - d[0] + d[1] && xx > x + d[0] && xx <= N - 1) { temp[yy][xx] = 2; ret += arr[yy][xx]; q.push({ yy,xx }); } } else if (num == 3) { if (yy >= y && yy <= N - 1 && xx >= 0 && xx < x + d[1]) { temp[yy][xx] = 3; ret += arr[yy][xx]; q.push({ yy,xx }); } } else { if (yy > y - d[0] + d[1] && yy <= N - 1 && xx >= x + d[1] && xx <= N - 1) { temp[yy][xx] = 4; ret += arr[yy][xx]; q.push({ yy,xx }); } } } } } } return ret; } int setMap() //5구역 표시 { for (int i = 0; i <= d[0]; i++) { int y1 = y - i; int x1 = x + i; int y2 = y + d[1] - i; int x2 = x + d[1] + i; temp[y1][x1] = 5; temp[y2][x2] = 5; } for (int i = 0; i <= d[1]; i++) { int y1 = y + i; int x1 = x + i; int y2 = y - d[0] + i; int x2 = x + d[0] + i; temp[y1][x1] = 5; temp[y2][x2] = 5; } int pop[6] = { 0 }; pop[5] = population; for (int i = 1; i <= 4; i++) { //각 구역별 인구수 구하기 pop[i] = bfs(i); pop[5] -= pop[i]; } sort(pop, pop + 6); int ret = pop[5] - pop[1]; return ret; } void dfs(int level) { if (level == 2) { if (x + d[0] + d[1] >= N || y + d[1] >= N || y - d[0] < 0) return; memset(temp, 0, sizeof(temp)); int ret = min(ans, setMap()); if (ret < ans) { //최솟값 ans에 저장 ans = ret; } return; } for (int i = 1; i <= N; i++) { //d1, d2의 조합 d[level] = i; dfs(level + 1); } } int main() { scanf("%d", &N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { scanf("%d", &arr[i][j]); population += arr[i][j]; } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { y = i; x = j; dfs(0); } } printf("%d", ans); } | cs |
'백준' 카테고리의 다른 글
[ 백준 ] 11723번 - 집합 (C++) (0) | 2022.09.18 |
---|---|
[ 백준 ] 21610번 - 마법사 상어와 비바라기 (C++) (0) | 2022.09.17 |
[ 백준 ] 5373번 - 큐빙 (C++) (0) | 2022.09.15 |
[ 백준 ] 17140번 - 이차원 배열과 연산 (C++) (0) | 2022.09.14 |
[ 백준 ] 16235번 - 나무 재테크 (C++) (0) | 2022.09.13 |