※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1780번 문제인 종이의 개수이다.
문제는 아래 링크를 확인하자.
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1의 세 값 중 하나가 저장되어 있다. 우리는 이 행렬을 적절한 크기로 자르려고 하는데, 이때 다음의 규칙에 따라 자르려고 한다.
www.acmicpc.net
이 문제는 분할정복(divide and conquer)으로 풀기 좋은 문제이다. 이 문제에서 다음과 같이 분할정복 알고리즘을 적용하자.
1) 만약 현재 조각이 한 값으로만 저장되어있다면 그 값의 종이가 하나 있는 것이다.
2) 그렇지 않다면, 종이를 가로 3등분, 세로 3등분 총 9조각 내어 각 조각에 대해 1부터 다시 진행한다.
아래는 제출한 소스코드이다.
#include <iostream>
using std::cin;
using std::cout;
int paper[2187][2187];
int m1 = 0, zero = 0, p1 = 0; // 각 종이의 개수를 세는 -1, 0, 1 변수
void solve(int N,int x, int y) {
int num = paper[x][y];
bool chk = true;
for (int i = x;i < x + N;i++) { // 하나의 수로 이루어진 조각인지 확인
for (int j = y;j < y + N;j++) {
if (paper[i][j] != num) {
chk = false;
}
if (!chk) break;
}
if (!chk) break;
}
if (chk) { // 하나의 수로 이루어진 조각이면 그 수에 대응되는 변수를 +1
if (num == 1) p1++;
else if (num == 0) zero++;
else m1++;
}
else { // 아니라면 조각을 다시 9조각내어 이를 반복
N /= 3;
solve(N, x, y);
solve(N, x + N, y);
solve(N, x + 2 * N, y);
solve(N, x, y + N);
solve(N, x + N, y + N);
solve(N, x + 2 * N, y + N);
solve(N, x, y + 2 * N);
solve(N, x + N, y + 2 * N);
solve(N, x + 2 * N, y + 2 * N);
}
}
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
int N;
cin >> N;
for (int i = 0;i < N;i++) {
for (int j = 0;j < N;j++) {
int temp;
cin >> temp;
paper[i][j] = temp;
}
}
solve(N, 0, 0);
cout << m1 << '\n' << zero << '\n' << p1;
return 0;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 1107 // C++] 리모컨 (0) | 2021.02.06 |
---|---|
[BOJ 7662 // C++] 이중 우선순위 큐 (0) | 2021.02.05 |
[BOJ 7569 // C++] 토마토 (0) | 2021.02.03 |
[BOJ 16236 // C++] 아기 상어 (0) | 2021.02.02 |
[BOJ 15686 // C++] 치킨 배달 (0) | 2021.02.01 |