개발/알고리즘 풀이

백준] 2630 색종이만들기

펭귀니 :) 2019. 10. 4. 21:32

색종이 만들기!

문제 그대로 돌렸다.

KeyPoint 

1. 들어온 색종이의 모든 칸이 같은 색의 색종이인지 확인.

2. 아니라면 먼저 사등분하여 각 등분에 대한 재귀를 돌리자!

3. 재귀함수에서는 해당 등분의 모든 칸이 같으면 리턴되고, 아니면 다시 사등분으로 나누는 재귀를 탄다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
/*
* 백준 2630 색종이 만들기
*/
public class Main {
	static boolean[][] visited;
	static int[][] map;
	static int whitecnt, bluecnt;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		int N = Integer.parseInt(in.readLine());
		map = new int[N][N];
		visited = new boolean[N][N];
		StringTokenizer st;

		boolean flag = true;
		int tmp = -1;
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(in.readLine());
			for (int j = 0; j < N; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if (i != 0 && j != 0 && map[i][j] != tmp) { // 전체가 같은지 확인
					flag = false;
				}
				tmp = map[i][j];
			}
		}

		if (flag) { // 만약 들어온 데이터가 색종이 하나라면
			if (map[1][1] == 1)
				bluecnt++;
			else
				whitecnt++;
		} else { 
			// 왼위 : 가로 1 ~ 2/N까지 / 세로 1 ~ 2/N까지
			// 오위 : 가로 2/N ~ N까지 / 세로 1 ~ 2/N까지
			// 왼아래 : 가로 1 ~ 2/N까지 / 세로 2/N ~ N까지
			// 오아래 : 가로 2/N ~ N까지 / 세로 2/N ~ N까지
      // 사등분 하자!
			re(0, N / 2, 0, N / 2); 
			re(N / 2, N, 0, N / 2);
			re(0, N / 2, N / 2, N);
			re(N / 2, N, N / 2, N);
		}

		System.out.println(whitecnt);
		System.out.println(bluecnt);

	}

	public static void re(int colstart, int colend, int rowstart, int rowend) {

		int tmp1 = map[rowstart][colstart];
		boolean flag = true;
		for (int r = rowstart; r < rowend; r++) {
			for (int c = colstart; c < colend; c++) {
				if (!visited[r][c] && tmp1 != map[r][c]) {
					flag = false;
					re(colstart, colstart + (colend - colstart) / 2, rowstart, rowstart + (rowend - rowstart) / 2);
					re(colstart + (colend - colstart) / 2, colend, rowstart, rowstart + (rowend - rowstart) / 2);
					re(colstart, colstart + (colend - colstart) / 2, rowstart + (rowend - rowstart) / 2, rowend);
					re(colstart + (colend - colstart) / 2, colend, rowstart + (rowend - rowstart) / 2, rowend);
				}
			}
		}

		if (flag) {
			if (tmp1 == 1)
				bluecnt++;
			else
				whitecnt++;

			for (int r = rowstart; r < rowend; r++) {
				for (int c = colstart; c < colend; c++) {
					visited[r][c] = true;
				}
			}
		}
	}

}

'개발 > 알고리즘 풀이' 카테고리의 다른 글

프로그래머스] 가장 큰 정사각형 찾기 (Java)  (0) 2020.02.10
SW Expert Academy] 1249 D4 보급로  (0) 2020.02.01
백준] 3055 탈출  (0) 2019.11.10
백준] 2636 치즈  (0) 2019.10.04
정올] 2247 도서관  (0) 2019.09.30