Study hard
(c++)백준 1780번: 종이의 개수 본문
https://www.acmicpc.net/problem/1780
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1의 세 값 중 하나가 저장되어 있다. 우리는 이 행렬을 적절한 크기로 자르려고 하는데, 이때 다음의 규칙에 따라 자르려고 한다.
www.acmicpc.net
[풀이]
분할 정복으로 풀었다.
종이의 크기가 1*1이거나 종이에 쓰여 있는 수가 모두 같을 경우 해당 수로 채워진 종이의 개수를 추가하였다.
만약 종이에 쓰여있는 수 중 다른 게 있으면 현재 종이를 9등분한 정보를 인수로 재귀함수를 호출하였다.
#include <iostream>
using namespace std;
#define Max 2187//3^7
int N;
int Paper[Max][Max];
int Minus = 0, Zero = 0, Plus = 0;//각각 종이의 개수
void getPaper(int startx, int starty, int curSize) {
//종이 크기가 1이면
if (curSize == 1) {
if (Paper[startx][starty] == -1)Minus++;
else if (Paper[startx][starty] == 0)Zero++;
else if (Paper[startx][starty] == 1)Plus++;
return;
}
for (int i = startx; i < startx + curSize; i++) {
for (int j = starty; j < starty + curSize; j++) {
//숫자 다른 게 있으면 재귀
if (Paper[startx][starty] != Paper[i][j]) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
//9등분하고 각각 종이의 첫 좌표를 인수로 재귀함수 호출
getPaper(startx + (curSize / 3)*k, starty + (curSize / 3)*l, curSize / 3);
}
}
return;
}
}
}
//숫자가 모두 같으면 해당 종이 개수 추가
if (Paper[startx][starty] == -1)Minus++;
else if (Paper[startx][starty] == 0)Zero++;
else if (Paper[startx][starty] == 1)Plus++;
return;
}
void solution() {
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> Paper[i][j];
}
}
getPaper(0, 0, N);
cout << Minus << endl << Zero << endl << Plus << endl;
}
int main() {
solution();
return 0;
}
'백준 > 분할 정복' 카테고리의 다른 글
(c++)백준 2448번: 별 찍기 - 11 (0) | 2020.06.30 |
---|---|
(c++)백준 2447번: 별 찍기 - 10 (0) | 2020.06.30 |
(c++)백준 1992번: 쿼드트리 (0) | 2020.06.30 |
(c++)백준 11729번: 하노이 탑 이동 순서 (0) | 2020.06.25 |
(c++)백준 11728번: 배열 합치기 (0) | 2020.06.25 |