백준 [17779] 게리맨더링2
문제보기
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N, ans;
static int[][] map;
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];
ans = 987654321;
for (int i = 1; i < N + 1; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 1; j < N + 1; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
seperate();
System.out.println(ans);
}
public static void seperate() {
for (int i = 1; i < N; i++) { // d1
for (int j = 1; j < N; j++) { // d2
standard(i, j);
}
}
}
public static void standard(int d1, int d2) {
for (int x = 1; x < N; x++) { // x
for (int y = 1; y < N; y++) { // y
boolean flag = false;
int max = 0;
int min = 987654321;
boolean[][] chk = new boolean[N + 1][N + 1];
if ((x >= x + d1 + d2) || (x + d1 + d2 > N) || (y - d1 < 1) || (y - d1 >= y) || (y >= y + d2)
|| (y + d2 > N)) {
flag = true;
continue;
} else {
// 1번 선거구
out: if (!flag) {
int sum = 0;
int idx = 0;
for (int i = 1; i < x + d1; i++) {
jump: for (int j = 1; j <= y; j++) {
if (!isRange(i, j)) {
flag = true;
break out;
}
if (i >= x && j >= y - idx) { // 경계선
idx++;
break jump;
}
chk[i][j] = true;
sum += map[i][j];
}
}
if (sum == 0)
flag = true;
else {
max = Math.max(max, sum);
min = Math.min(min, sum);
}
}
// 2번 선거구
out: if (!flag) {
int sum = 0;
int idx = 0;
for (int i = 1; i <= x + d2; i++) {
jump: for (int j = N; j > y; j--) {
if (!isRange(i, j)) {
flag = true;
break out;
}
if (i > x && j <= y + 1 + idx) { // 경계선
idx++;
break jump;
}
chk[i][j] = true;
sum += map[i][j];
}
}
if (sum == 0)
flag = true;
else {
max = Math.max(max, sum);
min = Math.min(min, sum);
}
}
// 3번 선거구
out: if (!flag) {
int sum = 0;
int idx = 0;
for (int i = x + d1; i <= N; i++) {
jump: for (int j = 1; j < y - d1 + d2; j++) {
if (!isRange(i, j)) {
flag = true;
break out;
}
if (i >= x + d1 && j >= y - d1 + idx) {
idx++;
break jump;
}
chk[i][j] = true;
sum += map[i][j];
}
}
if (sum == 0)
flag = true;
else {
max = Math.max(max, sum);
min = Math.min(min, sum);
}
}
// 4번 선거구
out: if (!flag) {
int sum = 0;
int idx = 0;
for (int i = x + d2 + 1; i <= N; i++) {
jump: for (int j = N; j >= y - d1 + d2; j--) {
if (!isRange(i, j)) {
flag = true;
break out;
}
if (i > x + d2 && j < y + d2 - idx) {
idx++;
break jump;
}
chk[i][j] = true;
sum += map[i][j];
}
}
if (sum == 0)
flag = true;
else {
max = Math.max(max, sum);
min = Math.min(min, sum);
}
}
// 5번 선거구
if (!flag) {
int sum = 0;
for (int i = x; i <= x + d1 + d2; i++) {
for (int j = y - d1; j <= y + d2; j++) {
if (!chk[i][j]) {
sum += map[i][j];
}
}
}
if (sum == 0)
flag = true;
else {
max = Math.max(max, sum);
min = Math.min(min, sum);
}
}
}
if (!flag) {
int diff = Math.abs(min - max);
ans = Math.min(diff, ans);
}
}
}
}
public static boolean isRange(int r, int c) {
return r >= 1 && c >= 1 && r <= N && c <= N;
}
}