https://www.acmicpc.net/problem/1992
1992번: 쿼드트리
첫째 줄에는 영상의 크기를 나타내는 숫자 N 이 주어진다. N 은 언제나 2의 제곱수로 주어지며, 1 ≤ N ≤ 64의 범위를 가진다. 두 번째 줄부터는 길이 N의 문자열이 N개 들어온다. 각 문자열은 0 또
www.acmicpc.net
분할 정복 문제이다.
왜 정수 입력이 안되지 의문이었는데, 띄어쓰기가 안 돼있는 걸 인식하지 못했었다. ㅋ
그래서 string으로 한 줄 받고 parsing 해주며 입력 부분을 처리했다.
그 다음 중요한 건 괄호 처리!
입력 순서는 아래와 같은 것을 확인했다.
이걸 참고해서 예제 1을 검사해보면
이렇게 된다.
영역이 시작할 때 괄호가 열려야 하고, 영역이 끝나면 괄호가 닫혀야 한다.
이것을 어떻게 구현할까 고민을 좀 했는데 분할 정복 코드 위/아래에 괄호를 넣어주는 것으로 해결했다.
또한 재귀 함수를 호출할 때 한 변의 길이가 2를 나눈 것만큼 감소하므로 n=n/2하여 넣어주었다.
cout << "("; // 시작 부분에 "(" 삽입
f(r, c, n); // 1영역
f(r, c + n, n); // 2영역
f(r + n, c, n); // 3영역
f(r + n, c + n, n); // 4영역
cout << ")"; // 끝 부분에 ")" 삽입
전체 코드는 아래와 같다.
#include <iostream>
#include <string>
using namespace std;
int N;
int A[65][65];
void f(int r, int c, int n) {
int flag = A[r][c]; bool isCorrect = true;
for (int i = r; i <= r + n - 1; i++) {
for (int j = c; j <= c + n - 1; j++) {
if (A[i][j] != flag) { // 영상이 모두 같은 숫자가 아니라면
isCorrect = false;
break;
}
}
if (!isCorrect) break;
}
if (isCorrect) {
// 주어진 영상의 번호가 다 일치하는 경우
cout << flag;
}
else {
// 쪼개야되는 경우
n /= 2;
cout << "("; // 시작 부분에 "(" 삽입
f(r, c, n); // 1영역
f(r, c + n, n); // 2영역
f(r + n, c, n); // 3영역
f(r + n, c + n, n); // 4영역
cout << ")"; // 끝 부분에 ")" 삽입
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
for (int i = 1; i <= N; i++) {
string x;
cin >> x;
// 문자열 자르기
for (int k = 1; k <= N; k++) {
A[i][k] = x[k - 1] - '0'; // 숫자로 변환
}
}
f(1, 1, N);
}
'백준' 카테고리의 다른 글
[10830] 행렬 곱셈 (0) | 2023.02.08 |
---|---|
[1629] 곱셈 (0) | 2023.02.06 |
[1780] 종이의 개수 (0) | 2023.02.03 |
[5430] AC (0) | 2023.01.31 |
[1021] 회전하는 큐 (0) | 2023.01.30 |
댓글