반응형

 

문제 : https://www.acmicpc.net/problem/2630

 

서론

분할정복 문제

 

풀이

표의 내용을 전수검사해서 전부 1이거나 전부 0이 아니면 4분할 한다.

4분할은 재귀를 통해 전부 1이거나 전부 0일때까지 반복한다.

전부 1이거나 전부 0이면 색종이 수를 +1해주고 리턴한다.

 

4분할의 좌표는 왼쪽 상단 지점을 (x1, y1), 오른쪽 하단 지점을 (x2, y2)로 하고 아래와 같이 분할한다.

1: x1, y1, (x1+x2)/2, (y1+y2)/2)
2: (x1+x2)/2+1, y1, x2, (y1+y2)/2)
3: x1, (y1+y2)/2+1, (x1+x2)/2, y2)
4: (x1+x2)/2+1, (y1+y2)/2+1, x2, y2)

 

구현

//c++

#include <iostream>

int map[129][129];
int blue;
int white;

void divide(int x1, int y1, int x2, int y2) {
	int cntBlue = 0;
	int cntWhite = 0;
	for (int i = y1; i <= y2; i++) {
		for (int j = x1; j <= x2; j++) {
			if (map[i][j] == 1) cntBlue++;
			else cntWhite++;
		}
	}

	//std::cout << x1 << " " << y1 << " " << x2 << " " << y2 << " " << std::endl;
	//std::cout << cntBlue << " " << cntWhite << std::endl;

	if (cntBlue == 0) { 
		white++; 
	}
	else if (cntWhite == 0) { 
		blue++;
	}
	else {
		divide(x1, y1, (x1+x2)/2, (y1+y2)/2); //1
		divide((x1+x2)/2+1, y1, x2, (y1+y2)/2); //2
		divide(x1, (y1+y2)/2+1, (x1+x2)/2, y2); //3
		divide((x1+x2)/2+1, (y1+y2)/2+1, x2, y2); //4
	}
	return;
}

int main() {
	int n;
	std::cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			int x;
			std::cin >> x;
			map[i][j] = x;
		}
	}

	divide(0, 0, n-1, n-1);
	std::cout << white << std::endl << blue;
}