본문 바로가기

IT/JAVA

백준 코딩 1780 : 종이의 개수

반응형

문제

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1의 세 값 중 하나가 저장되어 있다. 우리는 이 행렬을 적절한 크기로 자르려고 하는데, 이때 다음의 규칙에 따라 자르려고 한다.

  1. 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
  2. (1)이 아닌 경우에는 종이를 같은 크기의 9개의 종이로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.

이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구해내는 프로그램을 작성하시오.

입력

첫째 줄에 N(1≤N≤3^7, N은 3^k 꼴)이 주어진다. 다음 N개의 줄에는 N개의 정수로 행렬이 주어진다.

출력

첫째 줄에 -1로만 채워진 종이의 개수를, 둘째 줄에 0으로만 채워진 종이의 개수를, 셋째 줄에 1로만 채워진 종이의 개수를 출력한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static int[][] arr = null;
    static int plusPaper = 0;
    static int zeroPaper = 0;
    static int minusPaper = 0;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int length = Integer.parseInt(br.readLine()); //종이의 한 변의 길이 선언
        arr = new int[length][length]; // 길이 X 길이 의 종이를 2차원 배열로 선언
        for (int i = 0 ; i < length; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine()); // 한 줄마다 StringTokenizer로 배열에 요소를 넣는다.
            for (int j = 0 ; j < length;j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        square(0,0,length); // -1, 0, 1 종이의 개수를 반환하는 재귀함수 실행
        System.out.println(minusPaper);
        System.out.println(zeroPaper);
        System.out.println(plusPaper);
 
    }
 
    public static void square(int startX, int startY, int num) {
        if (num == 1) {
            if (arr[startX][startY] == 1) {
                plusPaper++
            } else if (arr[startX][startY] == 0){
                zeroPaper++;
            } else {
                minusPaper++;
            } 
            return;
        }
        int sum = 0;
        boolean flag = true
        // 처음부터 끝까지 모두 0이 나올경우 flag는 true 도중에 하나라도 0이 아닌 값이 나오면 false
        // 1 0 -1
        // -1 0 1
        // 0 0 0
        // 위처럼 flag를 설정하지 않고 단순히 누적값 sum이 0일때로 조건을 정해버린 경우 실제로 0으로 가득찬 종이가 아닌데도
        // sum == 0 되어 0으로 가득찬 종이로 판별해버릴 수가 있다.
        for (int i = startX ; i < startX + num; i++) {
            for (int j = startY ; j < startY + num; j++) {
                if (arr[i][j] != 0) {
                flag = false;
                sum += arr[i][j];
                }
            }
        }
        if (sum == num*num) { // 종이가 모두 1로 가득찼을때
            plusPaper++;
        } else if (sum == 0 && flag == true) { // 종이가 모두 0으로 가득 찼을때
            zeroPaper++;
        } else if (sum == -1*num*num) { // 종이가 모두 -1로 가득 찼을때
            minusPaper++;
        }else { // 그 이외의 경우 9부분으로 나누어 재귀함수를 실행한다.
            square(startX,startY,num/3);
            square(startX+num/3,startY,num/3);
            square(startX+(num/3)*2,startY,num/3);
            square(startX,startY+num/3,num/3);
            square(startX+num/3,startY+num/3,num/3);
            square(startX+(num/3)*2,startY+num/3,num/3);
            square(startX,startY+(num/3)*2,num/3);
            square(startX+num/3,startY+(num/3)*2,num/3);
            square(startX+(num/3)*2,startY+(num/3)*2,num/3);
        }
    }
}
 
cs

 

결과 화면

 

반응형

'IT > JAVA' 카테고리의 다른 글

백준 코딩 9012 : 괄호  (0) 2020.09.24
백준 코딩 2630 : 색종이 만들기  (0) 2020.09.22
백준 코딩 1966 : 프린터 큐  (0) 2020.09.19
백준 코딩 2164 : 카드2  (0) 2020.09.18
백준 코딩 2748 : 피보나치 수  (0) 2020.09.16