알고리즘/백준

백준 1780 종이의 개수 c++ [컴공과고씨]

시간빌게이츠 2022. 4. 3. 15:34
반응형

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

 

1780번: 종이의 개수

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수

www.acmicpc.net

문제 유형을 보고 분할정복을 떠올려 풀어준 문제이다.

각 변을 3씩 나누면서 보면 탐색하는 문제이다.

보면 처음에 9로 시작한다. 모든 원소가 같지 않다면 n/3으로 나누고 각 분면의 시작 좌표로 이동해주어야한다. 

​이런식의 좌표가 나온다. y가 행 x는 열.

 

 

단계별 풀이

1. 입력을 받아주고 papper 재귀함수로 들어간다.

2. bool 변수 선언 후 각 분면에 있는 원소들을 탐색해서 하나라도 다르면 bool 변수에 false를 저장

3. 만약 원소가 다른게 있었다면 9개로 잘라서 9분면에 넣어줌

4. 만약 모두 같다면 원소가 그 원소 수를 저장하는 변수에 +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
#include <iostream>
#include <cmath>
using namespace std;
int n;
int one = 0;
int m_one = 0;
int ze = 0;
int map[2200][2200];
void papper(int x, int y, int size){
    bool same = true;
    for (int i = y; i < y+size;i++){ //각 분면 탐색
        for (int j = x; j < x + size;j++){
            if(map[i][j] != map[y][x]){
                same = false// 원소 하나라도 다르면 false
                break;
            }
        }
        if(!same){
            break;
        }
    }
    if(!same){
        papper(x, y, size / 3); // 1번
        papper(x+size/3, y, size / 3); // 2번
        papper(x+size/3+size/3, y, size / 3); // 3번
        papper(x, y+size/3size / 3); // 4번
        papper(x, y+size/3+size/3size / 3); // 7번
        papper(x+size/3, y+size/3size / 3); // 5번
        papper(x+size/3+size/3, y+size/3+size/3size / 3); // 9번
        papper(x+size/3, y+size/3+size/3size / 3); // 8번
        papper(x+size/3+size/3, y+size/3size / 3); // 6번
    }else{
        if(map[y][x] == 1){
            one++// 1인 경우
        }else if(map[y][x] == -1){
            m_one++// -1인 경우
        }else{
            ze++// 0인 경우
        }
    }
}
 
int main(){
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 0; i < n;i++){
        for (int j = 0; j < n;j++){
            cin >> map[i][j];
        }
    }
    papper(00, n);
    cout << m_one << '\n';
    cout << ze << '\n';
    cout << one << '\n';
    return 0;
}// 28min
cs

 

난이도 걸린시간 참고 사용 알고리즘
28min x 분할정복
반응형