1 분 소요

key word : 재귀, 쿼드 트리, 분할 정복

문제

배열로된 종이에 모두 같은 숫자가 들어있는지 확인하는 문제이다. 다른 숫자가 들어있다면 종이를 9분할해서 또 같은 작업을 반복한다. 최종적으로 -1로만 채워진 종이, 0으로만 채워진 종이, +1로만 채워진 종이의 개수를 출력하면 된다.

직전에 풀었던 ‘색종이 만들기’문제와 매우 흡사하다. 백준에서 유형별 풀기로 재귀를 선택하고 만 명 안팎이 푼 문제들에 도전하다보니 유사한 문제를 연달아 풀게된 것 같다.



아이디어

이 문제도 어렵지 않게 풀 수 있었다. 배열을 돌며 같은 숫자인지 확인하고, 그렇지 않은 경우 재귀를 이용해 9분할한 종이에 대해 같은 작업을 반복했다. 단, 9분할하는 경우이므로 재귀함수를 호출할 때 인자를 잘 전달해야한다.

‘색종이 만들기’ 문제때와 달리 함수를 하나 더 만들어 사용했다. -1인지 0인지, 혹은 +1인지 확인하는 부분이 꽤 중복되는 것 같아 그걸 판별하고 알맞은 변수의 값을 올려주는 기능을 따로 빼줬다. 그런데 지금 다시 보니 base condition으로 둔 n = 1일 때를 따로 검사하지 않아도 정상적으로 동작하므로 그 부분을 빼는게 더 깔끔했을 것 같다.



구현

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;

public class PaperCount {
	static int N;
	static int[][] paper;
	static int minus = 0, zero = 0, plus = 0;

	public static void init() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		N = Integer.parseInt(br.readLine());
		paper = new int[N][N];

		for(int i=0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			for(int j=0; j<N; j++) {
				paper[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		br.close();
	}

	public static void recursion(int n, int r, int c) {
		int num = paper[r][c];

		if(n == 1) {
			add(num);
			return;
		}

		int size = n / 3;
		for(int i=r; i<n + r; i++) {
			for(int j=c; j<n + c; j++) {
				if(paper[i][j] != num) {
					recursion(size, r, c);
					recursion(size, r, c + size);
					recursion(size, r, c + 2 * size);
					recursion(size, r + size, c);
					recursion(size, r + size, c + size);
					recursion(size, r + size, c + 2 * size);
					recursion(size, r + 2 * size, c);
					recursion(size, r + 2 * size, c + size);
					recursion(size, r + 2 * size, c + 2 * size);
					return;
				}
			}
		}

		add(num);
	}

	public static void add(int num) {
		if(num == -1) {
			minus++;
		}else if(num == 0) {
			zero++;
		}else {
			plus++;
		}
		return;
	}


	public static void main(String[] args) throws IOException{
		init();
		recursion(N, 0, 0);
		System.out.println(minus);
		System.out.println(zero);
		System.out.println(plus);
	}

}

업데이트: