Seren dev's blog
article thumbnail
 

2630번: 색종이 만들기

첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다.

www.acmicpc.net

1. 풀이

재귀함수를 이용한 분할정복을 사용하여 문제를 풀 수 있다.

 

main 함수에서 전체 종이의 한 변의 길이 N과 색종이의 위치 정보를 입력받고

divideAndConquer() 재귀 함수를 호출하여 (0, 0)부터 색종이 배열 탐색을 시작한다.

divideAndConquer() 함수 내에서 인자로 받은 시작위치부터 색종이 배열을 탐색하다가, 시작 위치의 색과 다른 색을 발견하면 위 그림과 같이 색종이를 4등분하여 새로운 탐색을 시작해야 한다. 즉, 다음과 같이 4번의 재귀함수를 호출하고, 현재 진행중인 탐색은 계속할 필요가 없으므로 바로 return 한다.

<java />
// n은 현재 탐색하는 색종이의 크기, papers는 색종이 배열, x, y는 현재 탐색 시작 위치 static void divideAndConquer(int n, int[][] papers, int x, int y) { int startColor = papers[x][y]; ... for (int i = x; i < x + n; i++) { for (int j = y; j < y + n; j++) { if (papers[i][j] != startColor) { divideAndConquer(n / 2, papers, x, y); divideAndConquer(n / 2, papers, x + n / 2, y); divideAndConquer(n / 2, papers, x, y + n / 2); divideAndConquer(n / 2, papers, x + n / 2, y + n / 2); return; } } } ... }

만약 n이 1이거나, 인자로 주어진 n*n 크기만큼 배열을 모두 탐색했는데도 전부 같은 색이라면, 하얀색 색종이 또는 파란색 색종이의 개수를 업데이트한다.

 

2. 코드

<java />
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.*; class Main { static int whitePapers = 0; static int bluePapers = 0; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int[][] papers = new int[n][n]; StringTokenizer st; for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < n; j++) { papers[i][j] = Integer.parseInt(st.nextToken()); } } divideAndConquer(n, papers, 0, 0); System.out.println(whitePapers); System.out.println(bluePapers); } static void divideAndConquer(int n, int[][] papers, int x, int y) { int startColor = papers[x][y]; if (n == 1) { if (startColor == 1) bluePapers++; else whitePapers++; return; } for (int i = x; i < x + n; i++) { for (int j = y; j < y + n; j++) { if (papers[i][j] != startColor) { divideAndConquer(n / 2, papers, x, y); divideAndConquer(n / 2, papers, x + n / 2, y); divideAndConquer(n / 2, papers, x, y + n / 2); divideAndConquer(n / 2, papers, x + n / 2, y + n / 2); return; } } } if (startColor == 1) bluePapers++; else whitePapers++; } }
728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!