본문 바로가기
백준

[2630] 색종이 만들기

by kmyobin 2022. 11. 8.


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

 

2630번: 색종이 만들기

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

www.acmicpc.net

분할 정복, 재귀 문제이다.

 

만든 정사각형 안이 모두 같은 색이 될 때까지 쪼개야한다. 0이면 흰색, 1이면 파란색을 뜻한다.

 

그래서 정해진 구간에서 모두 같은 색을 갖고있는지 판별한 후, 

다른 색이 있다면 더 쪼개고(분할), 같은 색이라면 흰색인지 파란색인지 판별하여 count해준다.

 

 

작은 정사각형으로 쪼갤 때 총 4개의 정사각형이 새로 생긴다.

그래서 그림을 참고하여 1구간, 2구간, 3구간, 4구간으로 쪼개주었다.

쪼갠 정사각형 구간 한 변의 길이는 모두 N/2인 것을 볼 수 있다.

 

 

그렇게 완성된 코드이다.

#include <iostream>
using namespace std;

// 0 : white, 1 : blue

int N; int A[129][129];
int white, blue;

void cut(int x, int y, int n) {
	int color = A[x][y]; // 이 구간의 color를 구함
	bool diff = false;

	// 정해진 구간에서 모두 같은 색인지 판별
	for (int i = x; i <= x + n-1; i++) {
		for (int j = y; j <= y + n-1; j++) {
			if (color != A[i][j]) { // 색이 다르다면 
				diff = true; // 빠져나오기
				break;
			}
		}
		if (diff) break;
	}

	if (diff) { // 색이 구간 안에서 다르다면
		// 더 쪼개기
		cut(x, y, n / 2); // 1구간 (왼쪽 위)
		cut(x + n / 2, y, n / 2); // 2구간 (오른쪽 위)
		cut(x, y + n / 2, n / 2); // 3구간 (왼쪽 아래)
		cut(x + n / 2, y + n / 2, n / 2); // 4구간 (오른쪽 아래)
	}
	else {
		if (color == 0) white++;
		else blue++;
	}
}


int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> N;

	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= N; j++)
		{
			cin >> A[i][j];
		}
	}

	cut(1, 1, N);

	printf("%d\n%d", white, blue);
}

'백준' 카테고리의 다른 글

[2448] 별 찍기 - 11  (0) 2022.11.13
[1074] Z  (0) 2022.11.12
[1406] 에디터  (0) 2022.11.07
[1158] 요세푸스 문제  (0) 2022.11.06
[10866] 덱  (0) 2022.11.04

댓글