-
[KOITP] 나누기자료구조 및 알고리즘/문제풀이 2017. 1. 18. 08:34
출 처 : http://koitp.org/problem/SDS_PRO_7_4/read/
시간 제한 메모리 제한 제출 횟수 정답 횟수 (비율) 정답자 수 1.0 초 32768 MB 587 387 (66%) 328 < Comment >
풀면서도 이런 막무가내식 풀이가 풀리나 싶긴 했지만 기본적으로 N이 작기 때문에 O(N^2lgN) 정도의 시간복잡도는 괜찮다고 합니다. 해당 문제는 꽤 여러번 본 것 같은데, 일반적인 분할정복 문제였습니다. 기본 사상은 그냥 전체 색종이 색이 같은지 판별하고, 같으면 카운트를 늘려주고, 다르면 한번 더 재퀴호출로 4분할해주는 방식입니다.
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.StringTokenizer; import javax.crypto.CipherInputStream; public class Devide { public static int N = 0; public static int paper[][] = null; public static int count0 = 0; public static int count1 = 0; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); N = Integer.parseInt(br.readLine()); paper = new int[N][N]; StringTokenizer st = null; for (int i = 0 ; i < N ; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0 ; j < N ; j++) { paper[i][j] = Integer.parseInt(st.nextToken()); } } cutPaper(0, 0, N); bw.write("" + count0 + "\n"); bw.write("" + count1 + "\n"); bw.flush(); bw.close(); } public static void cutPaper(int leftx, int lefty, int n) { if (n == 1) { if (paper[leftx][lefty] == 1) { count1++; } else { count0++; } return; } boolean isSameColor = false; label : for (int i = leftx ; i < leftx + n - 1 ; i++) { for (int j = lefty ; j < lefty + n - 1; j++) { if (paper[i][j] != paper[i][j + 1] || paper[i][j] != paper[i + 1][j] || paper[i][j] != paper[i+1][j+1]) { isSameColor = false; break label; } } isSameColor = true; } if(isSameColor) { if (paper[leftx][lefty] == 1) { count1++; } else { count0++; } return; } cutPaper(leftx, lefty, n/2); cutPaper(leftx, lefty + n/2, n/2); cutPaper(leftx + n/2, lefty, n/2); cutPaper(leftx + n/2, lefty + n/2, n/2); } }