백준 1780 - 종이의 개수
Updated:
Java
1780 번 - 종이의 개수
문제
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1의 세 값 중 하나가 저장되어 있다. 우리는 이 행렬을 적절한 크기로 자르려고 하는데, 이때 다음의 규칙에 따라 자르려고 한다.
- 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
- (1)이 아닌 경우에는 종이를 같은 크기의 9개의 종이로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.
이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구해내는 프로그램을 작성하시오.
접근 방법
분할 정복의 기초적인 문제이다.
n x n 크기의 행렬을 전부 탐색하여 다 동일한 값이면 그 값의 개수를 1 증가하고,
하나라도 다르면, n/3 x n/3으로 총 9개로 나누어 각각 탐색한다.
구현
매개변수로 시작점 y,x와 탐색 할 크기 size를 전달하는 Paper
재귀 함수를 선언한다.
size가 1이면 해당하는 값의 개수를 1 증가한다.
탐색 시작점을 y,x로 두어 size만큼 행렬을 탐색하여 같으면 종료, 다르면 재 탐색한다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, minus = 0, zero = 0, plus = 0;
static int[][] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
n = stoi(br.readLine());
arr = new int[n][n];
for(int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
for(int j = 0; j < n; j++) {
arr[i][j] = stoi(stk.nextToken());
}
}
Paper(0,0,n);
System.out.println(minus);
System.out.println(zero);
System.out.println(plus);
br.close();
}
static void Paper(int y, int x, int size) {
if(size == 1) {
check(arr[y][x]);
return;
}
// 기준 값
int pivot = arr[y][x];
boolean isSame = true;
end : for(int i = y; i < size + y; i++) {
for(int j = x; j < size + x; j++) {
if(pivot != arr[i][j]) {
isSame = false;
break end;
}
}
}
// 모두 동일한 값일 때
if(isSame)
check(pivot);
// n / 3 * n / 3으로 나누어 재 탐색한다.
else {
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
Paper(y + i * (size / 3), x + j * (size / 3), size / 3);
}
}
}
}
static void check(int num) {
switch(num) {
case -1:
minus++;
break;
case 0:
zero++;
break;
case 1:
plus++;
break;
}
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}
총평
난이도
⭐⭐★★★
후기
개선할 점
없