알고리즘/백준
2630 색종이 만들기
흰싸라기
2022. 3. 17. 18:45
백준 2630 색종이 만들기 : https://www.acmicpc.net/problem/2630
2630번: 색종이 만들기
첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다.
www.acmicpc.net
분할 정복 문제는 간단히 말하면,
문제를 나누어 풀어 작은 문제의 답을 구해 그 답을 합치면서 최종 문제의 답을 구하는 것
즉, 재귀로 풀면 좋을 것
[문제를 풀기 전 생각한 것 ]
① n/2가 1이 될 때 까지 나누고 합치면서 값을 계산할 것
② 재귀 함수 구성
- 정사각형을 1, 2, 3, 4로 나누기 (순서는 아래 그림 참고)
- 1, 2, 3, 4가 가리키는 값이 같으면 return을 그 값으로 할 것
- 값이 다르면, 각 번호가 가리키는 색의 색종이 값 증가 및 return 값을 0, 1이 아닌 수로 할 것
[문제 풀이]
#include <iostream>
using namespace std;
int cut(int** c_paper, int size, int n, int x, int y, int(&num)[2]) { // 색종이 자르기
int dn = n / 2;
if (dn < 1) return c_paper[x][y];
int one = cut(c_paper, size, dn, x, y, num);
int two = cut(c_paper, size, dn, x, y + dn, num);
int three = cut(c_paper, size, dn, x + dn, y, num);
int four = cut(c_paper, size, dn, x + dn, y + dn, num);
if (one == two && two == three && three == four) {
if (size == n && one != 2) num[one]++;
return one;
}
else {
if (one != 2) num[one]++;
if (two != 2) num[two]++;
if (three != 2) num[three]++;
if (four != 2) num[four]++;
return 2;
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin >> n;
int** c_paper;
c_paper = new int*[n]; // 배열 할당
for (int i = 0; i < n; i++) {
c_paper[i] = new int[n];
}
int k;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> k;
c_paper[i][j] = k; // 값 저장
}
}
int num[2] = {0, 0}; //0 : white, 1 : blue
cut(c_paper, n, n, 0, 0, num); // 색종이 자르기
cout << num[0] << "\n" << num[1];
for (int i = 0; i < n; i++) { // 배열 삭제
delete[] c_paper[i];
}
delete[] c_paper;
return 0;
}
int** c_paper | 색종이 색을 저장하는 배열 | |
int num[2] | 색종이 색별 개수를 저장하는 배열로 0은 하얀색, 1은 파란색 개수를 저장 | |
int cut(int** c_paper, int size, int n, int x, int y, int(&num)[2]) | int size | 전체 종이의 한 변의 길이 |
int n | 현재 확인하는 종이의 한 변의 길이 | |
int x, int y | 1, 2, 3, 4 위치를 구분하기 위한 위치 정보 | |
① 한 변의 길이가 1보다 작은 경우 현재 위치값 return ② 정사각형을 네 개로 나누어 각각 확인 ③ 네 개의 값이 모두 동일하면 현재 값 return (단, 현재 한 변의 길이가 전체 종이의 한 변의 길이면 num을 증가시키고 return) ④ 값이 다르면, 각자 저장된 값에 대한 num 증가 후 0,1이 아닌 2를 return 주의) num이 2인 경우 배열 값이 증가되지 않도록 |
[comment]
생각보다 쉽게 풀린 문제 였다.
다 풀고나니 그냥 num 배열을 num[3]으로 설정했으면, 따로 조건 설정을 안했어도 됐겠다는 생각이..