알고리즘/백준 단계별로 풀기 (12.26 ~ 12.31)

분할정복 - 백준 2630번 색종이 만들기

잡담연구소 2020. 12. 27. 09:59

www.acmicpc.net/problem/2630

 

2630번: 색종이 만들기

첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다.

www.acmicpc.net

IDEA 

계속 4등분으로 쪼개주면 된다. 

쪼갠 후 그 네모난 영역에 대해서 이중 for문을 통해 다 한 숫자(0 혹은 1)로 이뤄져있는지 확인해준다.

0이면 white 를 카운트해주고 1이면 blue 를 카운트해준다. 

전체 영역의 개수 $n^{2}$과 white /blue 중 하나가 같다면 한 숫자로만 이루어져있다는 뜻이다. 

한 숫자로 이루어져있다면 더이상 쪼개지 않고 return 해버린다.

만약 한 숫자로만 이루어져있지 않다면 또 4등분을 하며 1x1이 될 때까지 쪼개준다. 

 

CODE

#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;

int arr[130][130] , blue_cnt = 0 , white_cnt = 0;

void divide(int start_row, int start_col , int n ){
	int blue=0, white=0;
	for (int i = start_row; i < start_row + n; i++) {
		for (int j = start_col; j < start_col + n; j++) {
			arr[i][j] == 1 ? blue++ : white++;
		}
	}
	if (blue == n * n ) //모두 한 색깔로 채워져있는 경우
	{
		blue_cnt++;
		return;
	}
	else if (white == n * n) {
		white_cnt++;
		return;
	}
	else {
		divide(start_row, start_col, n / 2);
		divide(start_row + n/2, start_col, n / 2);
		divide(start_row, start_col + n/2, n / 2);
		divide(start_row + n/2, start_col + n/2, n / 2);
	}
}


int main() {
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			scanf("%d", &arr[i][j]);
		}
	}
	divide(0, 0, n); 
	printf("%d\n%d", white_cnt , blue_cnt);
}