danbibibi
article thumbnail

1. 문제

문제 바로가기> BOJ 17779번: 게리맨더링 2

 

17779번: 게리맨더링 2

재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름

www.acmicpc.net

 

2. 풀이

얼핏 보면 조건이 굉장히 까다로워 보이지만,,

사실 문제에서 경계의 범위를 다 주고 있기 때문에,, 그대로 조건식만 넣어주면 된다! 사실 개꿀인 ㅎ

나름 중요한 포인트? 가 있다면, 5번 구역의 경계를 먼저 설정해 두고, 그 경계만 침범?하지 않도록 해주면 된다!

이 후 `모든 인구 수 - 1,2,3,4 지역 인구` 를 해주면 5번 구역 인구도 쉽게 구할 수 있다!!

아무래도 그림으로 보면 이해가 더 쉬울 것 같아서, 그려보았다 ㅎㅎ

 

 

2.0.1. C++

<cpp />
#include<iostream> #include<cstring> #include<algorithm> #define INF 1000000001 #define MAX 101 using namespace std; int ans = INF; int N, total=0; bool border[MAX][MAX]; int dx[] = {1, 1, -1, -1}; int dy[] = {1, -1, -1, 1}; int A[MAX][MAX], population[5]; void input() { cin >> N; for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { cin >> A[i][j]; total+=A[i][j]; } } } int diff(int x, int y, int d1, int d2) { memset(population, 0, sizeof(population)); // 인구 수 memset(border, false, sizeof(border)); // 경계선 int nx = x, ny = y; int mvoe_cnt[] = {d2, d1, d2, d1}; for(int d=0; d<4; d++){ for(int i=0; i<mvoe_cnt[d]; i++){ nx+=dx[d]; ny+=dy[d]; border[nx][ny] = true; // 경계 설정 } } // 좌측 상단 (1번 선거구) for(int r=1; r<x+d1; r++){ // 1 ≤ r < x+d1 for(int c=1; c<=y && !border[r][c]; c++) population[0]+=A[r][c]; // 1 ≤ c ≤ y } // 우측 상단 (2번 선거구) for(int r=1; r<=x+d2; r++){ // 1 ≤ r ≤ x+d2 for(int c=N; c>y && !border[r][c]; c--) population[1]+=A[r][c]; // y < c ≤ N } // 좌측 하단 (3번 선거구) for(int r=x+d1; r<=N; r++){ // x+d1 ≤ r ≤ N for(int c=1; c<y-d1+d2 && !border[r][c]; c++) population[2]+=A[r][c]; // 1 ≤ c < y-d1+d2 } // 우측 하단 (4번 선거구) for(int r=x+d2+1; r<=N; r++){ // x+d2 < r ≤ N for(int c=N; c>=y-d1+d2 && !border[r][c]; c--) population[3]+=A[r][c]; // y-d1+d2 ≤ c ≤ N } population[4] = total; for(int i=0; i<4; i++) population[4]-=population[i]; // 5번 선거구 sort(population, population+5); // 정렬 return population[4]-population[0]; // 최대 - 최소 } void solution() { for (int d1=1; d1<N; d1++) { // d1, d2 ≥ 1 for (int d2=1; d2<N; d2++) { for (int x=1; x<=N-d1-d2; x++) { // 1 ≤ x < x+d1+d2 ≤ N for (int y=d1+1; y<=N-d2; y++) // 1 ≤ y-d1 < y < y+d2 ≤ N ans = min(ans, diff(x, y, d1,d2)); } } } cout << ans; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); input(); solution(); }

 

2.0.2. Java

<java />
import java.io.*; import java.util.*; public class Main { private static final int INF = 1000000001; private static boolean[][] border; private static int[] population; private static int[][] A; private static int dx[] = {1, 1, -1, -1}; private static int dy[] = {1, -1, -1, 1}; private static int N, total=0, ans = INF; public static void main(String[] args) throws Exception { // System.setIn(new FileInputStream("res/input.txt")); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); // input N = Integer.parseInt(st.nextToken()); A = new int[N+1][N+1]; for (int i = 1; i <= N; i++) { st = new StringTokenizer(br.readLine()); for (int j = 1; j <= N; j++) { A[i][j] = Integer.parseInt(st.nextToken()); total+=A[i][j]; } } solution(); } private static void solution() { for (int d1=1; d1<N; d1++) { // d1, d2 ≥ 1 for (int d2=1; d2<N; d2++) { for (int x=1; x<=N-d1-d2; x++) { // 1 ≤ x < x+d1+d2 ≤ N for (int y=d1+1; y<=N-d2; y++) // 1 ≤ y-d1 < y < y+d2 ≤ N ans = Math.min(ans, diff(x, y, d1,d2)); } } } System.out.println(ans); } private static int diff(int x, int y, int d1, int d2) { population = new int[5]; border = new boolean[N+1][N+1]; int nx = x, ny = y; int mvoe_cnt[] = {d2, d1, d2, d1}; for(int d=0; d<4; d++){ for(int i=0; i<mvoe_cnt[d]; i++){ nx+=dx[d]; ny+=dy[d]; border[nx][ny] = true; // 경계 설정 } } // 좌측 상단 (1번 선거구) for(int r=1; r<x+d1; r++){ // 1 ≤ r < x+d1 for(int c=1; c<=y && !border[r][c]; c++) population[0]+=A[r][c]; // 1 ≤ c ≤ y } // 우측 상단 (2번 선거구) for(int r=1; r<=x+d2; r++){ // 1 ≤ r ≤ x+d2 for(int c=N; c>y && !border[r][c]; c--) population[1]+=A[r][c]; // y < c ≤ N } // 좌측 하단 (3번 선거구) for(int r=x+d1; r<=N; r++){ // x+d1 ≤ r ≤ N for(int c=1; c<y-d1+d2 && !border[r][c]; c++) population[2]+=A[r][c]; // 1 ≤ c < y-d1+d2 } // 우츨 하단 (4번 선거구) for(int r=x+d2+1; r<=N; r++){ // x+d2 < r ≤ N for(int c=N; c>=y-d1+d2 && !border[r][c]; c--) population[3]+=A[r][c]; // y-d1+d2 ≤ c ≤ N } population[4] = total; for(int i=0; i<4; i++) population[4]-=population[i]; // 5번 선거구 Arrays.sort(population); return population[4]-population[0]; // 최대 - 최소 } }

 

'문제 풀이 > SW 역량 테스트' 카테고리의 다른 글

BOJ 17837번: 새로운 게임 2  (0) 2023.02.08
BOJ 15684번: 사다리 조작  (0) 2023.02.06
BOJ 17140번: 이차원 배열과 연산  (0) 2023.02.02
BOJ 17142번: 연구소 3  (0) 2023.02.01
BOJ 16235번: 나무 재테크  (0) 2023.01.31
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로