득이공간

[백준 C++] 2630 색종이 만들기 - 분할정복 본문

PS/알고리즘 문제풀이

[백준 C++] 2630 색종이 만들기 - 분할정복

쟁득 2024. 2. 15. 09:44
 

2630번: 색종이 만들기

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

www.acmicpc.net

#include <iostream>
using namespace std;

int Paper[128][128];
int CountWhite;
int CountBlue;

void DividePaper(int StartRow, int StartCol, int Size)
{
	bool bDivide = false;
	int ColorCheck = -1;

	for (int i = StartRow; i < StartRow + Size; ++i)
	{
		for (int j = StartCol; j < StartCol + Size; ++j)
		{
			if ((ColorCheck == 0 && Paper[i][j] == 1)
				||
				(ColorCheck == 1 && Paper[i][j] == 0))
			{
				bDivide = true;
				break;
			}

			ColorCheck = Paper[i][j];
		}

		if (bDivide)
		{
			break;
		}
	}

	if (bDivide)
	{
		DividePaper(StartRow, StartCol, Size / 2);
		DividePaper(StartRow + Size / 2, StartCol, Size / 2);
		DividePaper(StartRow, StartCol + Size / 2, Size / 2);
		DividePaper(StartRow + Size / 2, StartCol + Size / 2, Size / 2);
	}
	else
	{
		if (ColorCheck == 0)
		{
			++CountWhite;
		}
		else if (ColorCheck == 1)
		{
			++CountBlue;
		}
	}
}

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

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

	DividePaper(0, 0, N);

	cout << CountWhite << '\n';
	cout << CountBlue << '\n';
}

 

재귀 함수를 이용해서 푸는 분할 정복 유형의 문제입니다.

주어진 범위 내에서 색이 모두 같다면 해당 색을 카운트 +1 해주고

색이 모두 같지 않다면 4등분 하도록 해서 풀었습니다.

모든 재귀함수가 수행된 후에 각각 카운트한 색상의 수를 출력하도록 했습니다.