BOJ

백준 1780 - 종이의 개수

yanJuicy 2020. 3. 23. 06:35
반응형

문제

 

https://www.acmicpc.net/problem/1780

 

1780번: 종이의 개수

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1의 세 값 중 하나가 저장되어 있다. 우리는 이 행렬을 적절한 크기로 자르려고 하는데, 이때 다음의 규칙에 따라 자르려고 한다. 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다. (1)이 아닌 경우에는 종이를 같은 크기의 9개의 종이로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다. 이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으

www.acmicpc.net

 

 

풀이

 

N * N 배열 안에 모든 수를 검사한다. 검사 시작점은 왼쪽 위를 기준으로 한다. 만약 모든 수가 같지 않으면 배열을 9개로 나누고 각 배열에서도 왼쪽 위를 검사 시작점으로 검사를 진행하면 된다. 

주어진 N은 3의 제곱 배수다. 그리고 배열의 모든 수가 같지 않으면 똑같은 크기로 9개를 나눠야 하므로 N을 3으로 나눈 수로 배열을 나눠주면 된다. 

이중 for문을 이용해서 9개로 나눈 배열에 대해서 재귀함수를 호출해서 문제를 해결할 수 있다.

 

 

코드

 

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
#include <iostream>
 
using namespace std;
 
const int MAX = 3*3*3*3*3*3*3;
 
int N;
int arr[MAX][MAX];
int result[3];
 
bool check(int x, int y, int n)
{
    int v = arr[x][y];
 
    for (int i=x; i<x+n; i++)
    {
        for (int j=y; j<y+n; j++)
        {
            if (arr[i][j] != v)
                return false;
        }
    }
 
    return true;
}
 
void f(int x, int y, int n) 
{
   if (check(x, y, n))
   {
       result[arr[x][y]+1]++;
       return;
   }
 
   int m = n/3;
   for (int i=0; i<3; i++)
        for (int j=0; j<3; j++)
            f(x + i*m, y + j*m, m);
}
 
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
 
    cin >> N;
    for (int i=0; i<N; i++)
        for (int j=0; j<N; j++)
            cin >> arr[i][j];
 
    f(00, N);
 
    for (int i=0; i<3; i++)
        cout << result[i] << '\n';
 
    return 0;
}
cs

 

반응형

'BOJ' 카테고리의 다른 글

백준 11729 - 하노이 탑 이동 순서  (0) 2020.03.24
백준 1107 - 리모컨  (0) 2020.03.24
백준 1080 - 행렬  (0) 2020.03.22
백준 1377 - 버블 소트  (0) 2020.03.10
백준 6064 - 카잉 달력  (0) 2020.03.09