Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 플로이드-와샬
- 문자열
- 완전탐색
- java
- swea
- JUnit 5
- 이분탐색
- 프로그래머스
- 그리디
- 후니의 쉽게 쓴 시스코 네트워킹
- BFS
- 백준
- 투 포인터
- 위상정렬
- 세그먼트 트리
- 알고리즘
- 동적계획법
- Effective Java
- 시뮬레이션
- Kotlin
- 백트래킹
- CS
- 구현
- Network
- 에라토스테네스의 체
- 유니온 파인드
- dfs
- 스택
- mst
- 수학
Archives
반갑습니다!
[백준] 17779 게리맨더링 2 본문
풀이
구현하기가 상당히 까다롭다. 모든 경우를 확인하여 해결하였다.
문제에 명시된 d1, d2 ≥ 1, 1 ≤ x < x+d1+d2 ≤ N, 1 ≤ y-d1 < y < y+d2 ≤ N 조건을 만족하는 d1과 d2를 찾아서 구역을 나눴다.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int map[21][21];
bool line[21][21];
int area[5];
int countArea(int x, int y, int d1, int d2) {
memset(line, 0, sizeof(line));
memset(area, 0, sizeof(area));
// 왼쪽 아래 방향으로 내려가는 경계 생성
for (int i = 0; i <= d1; i++) {
line[x + i][y - i] = true;
line[x + d2 + i][y + d2 - i] = true;
area[4] += (map[x + i][y - i] + map[x + d2 + i][y + d2 - i]);
}
// 오른쪽 아래 방향으로 내려가는 경계 생성
for (int i = 1; i < d2; i++) {
line[x + i][y + i] = true;
line[x + d1 + i][y - d1 + i] = true;
area[4] += (map[x + i][y + i] + map[x + d1 + i][y - d1 + i]);
}
// 5번 선거구 합 구하기
for (int i = x + 1; i < x + d1 + d2; i++) {
bool find = false;
for (int j = 1; j <= n; j++) {
if (line[i][j] == true && find == false) find = true;
else if (line[i][j] == false && find == true) {
line[i][j] = true;
area[4] += map[i][j];
}
else if (line[i][j] == true && find == true) break;
}
}
// 1, 2, 3, 4 선거구의 합 구하기
for (int r = 1; r <= n; r++) {
for (int c = 1; c <= n; c++) {
if (line[r][c]) continue;
if (r < x + d1 && c <= y) area[0] += map[r][c];
else if (r <= x + d2 && y < c) area[1] += map[r][c];
else if (x + d1 <= r && c < y - d1 + d2) area[2] += map[r][c];
else if (x + d2 < r && y - d1 + d2 <= c) area[3] += map[r][c];
}
}
int max_value = 0;
int min_value = 987654321;
for (int i = 0; i < 5; i++) {
max_value = max(max_value, area[i]);
min_value = min(min_value, area[i]);
}
return max_value - min_value;
}
int divide() {
int ret = 987654321;
// x와 y를 문제에 명시된 볌위로 탐색
for (int x = 1; x <= n - 2; x++) {
for (int y = 2; y < n - 1; y++) {
// d1과 d2를 1씩 증가시키며 조건을 만족하는지 확인
for (int d1 = 1; d1 < n; d1++) {
for (int d2 = 1; d2 < n; d2++) {
if (x + d1 + d2 <= n && y - d1 >= 1 && y + d2 <= n) ret = min(ret, countArea(x, y, d1, d2));
else break;
}
}
}
}
return ret;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> map[i][j];
cout << divide() << '\n';
return 0;
}
'알고리즘 문제 풀이' 카테고리의 다른 글
[백준] 6588 골드바흐의 추측 (0) | 2020.04.20 |
---|---|
[백준] 15486 퇴사 2 (0) | 2020.04.20 |
[백준] 2407 조합 (0) | 2020.04.20 |
[백준] 1300 K번째 수 (0) | 2020.04.20 |
[백준] 17837 새로운 게임2 (2) | 2020.04.19 |