문제 출처 : BOJ 1780 - 종이의 개수 https://www.acmicpc.net/problem/1780
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수
www.acmicpc.net
내가 아주 어려워하는 분할 정복 문제이다.
N*N 크기의 행렬에서 종이가 모두 같은 수로 되어 있다면 그대로 놔두고,
다른 수가 하나라도 있으면 종이를 9개로 자르는 것을 계속 반복하는 것이다.
이 문제는 재귀함수만 잘 작성한다면
분할 정복 문제 중에서는 그나마 쉽게 풀 수 있는 문제 같다.
최종 코드
#include <iostream>
#include <map>
#define MAX 2188
using namespace std;
int arr[MAX][MAX];
map<int, int> ans;
int N;
void f(int x, int y, int n) {
if (n == 1) {
ans[arr[x][y]]++;
return;
}
map<int, int> tmp;
for (int i = x; i < x + n; i++)
for (int j = y; j < y + n; j++)
tmp[arr[i][j]]++;
if (!tmp[0] && !tmp[1]) { ans[-1]++; return; }
else if (!tmp[-1] && !tmp[1]) { ans[0]++; return; }
else if (!tmp[-1] && !tmp[0]) { ans[1]++; return; }
for (int i = x; i < x + n; i += n / 3)
for (int j = y; j < y + n; j += n / 3)
f(i, j, n / 3);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N;
for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> arr[i][j];
f(0, 0, N);
cout << ans[-1] << '\n' << ans[0] << '\n' << ans[1] << '\n';
return 0;
}
'BOJ' 카테고리의 다른 글
(C++) BOJ/백준 10830 - 행렬 제곱 (0) | 2021.09.28 |
---|---|
(C++) BOJ/백준 3584 - 가장 가까운 공통 조상 (0) | 2021.09.28 |
(C++) BOJ/백준 1058 - 친구 (0) | 2021.09.27 |
(C++) BOJ/백준 1120 - 문자열 (0) | 2021.09.27 |
(C++) BOJ/백준 1699 - 제곱수의 합 (0) | 2021.09.26 |