일지

JUNGOL...120

niamdank 2021. 8. 24. 21:40

Intermediate_Coder/분할정복/색종이 만들기2(4진트리)


문제                                            

재우는 분할정복을 공부중이다.

그래서 1335:색종이 만들기 문제를 풀었다.

좀 더 공부하고 싶은 재우는​ 다음과 같은 문제를 생각해 보았다.

 

한 변의 길이가 2의 제곱수인 정사각형에 주어질 때,

주어진 정사각형에 포함된 숫자가 모두 0이면 0,

주어진 정사각형에 포함된 숫자가 모두 1이면 1 로 나타낸다.

그렇지 않고 주어진 정사각형에 포함된 숫자가 0, 1이 함께 있다면 

대문자 X로 그 영역을 나타내고 해당 영역을 4등분하여

재귀적으로 호출하여 같은 규칙을 적용한다.

4등분한 영역의 호출 순서는 좌상, 우상, 좌하, 우하 이다.

 

예를 들면 아래와 같은 정보가 주어지면

8

1 0 1 1 1 1 1 1

0 1 1 1 1 1 1 1

0 0 0 0 1 1 1 1

0 0 0 0 1 1 1 1

1 1 0 0 0 0 0 0

1 1 0 0 0 0 0 0

0 0 1 1 0 0 0 0

0 0 1 1 0 0 0 0​ 

 

위의 규칙을 따르면 다음과 같은 결과가 만들어진다.

XXX10011001X10010​  

 

입력 형식                                     

첫 행에 한 변의 길이 N이 입력된다. 
(8 <= N <= 1024, N은 2의 제곱수) 다음 하나의 행에 정보가 입력된다.

 

출력 형식                                     

규칙에 따라 만들어진 문자열을 출​력한다.

 

입력 예                                        

8
1 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0
0 0 1 1 0 0 0 0
0 0 1 1 0 0 0 0

 

출력 예                                        

XXX10011001X10010​


MakeColoredPaper2.h

#include <iostream>

class MakeColoredPaper2 : public Base
{
private:
	void CheckColoredPapers(int** arr, int n, int x, int y);
	bool IsAllSame(int** arr, int n, int x, int y);
};

 

MakeColoredPaper2.cpp

void MakeColoredPaper2::Code()
{
	int n;

	std::cin >> n;

	int** arr = new int* [n];
	for (int i = 0; i < n; i++)
	{
		arr[i] = new int[n];
	}

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

	CheckColoredPapers(arr, n, 0, 0);

	for (int i = 0; i < n; i++)
	{
		delete[] arr[i];
	}
	delete[] arr;
}

/// <summary>
/// 색종이의 영역을 확인하여 영역의 상태를 재귀적으로 출력한다.
/// </summary>
/// <param name="arr">배열</param>
/// <param name="n">영역의 크기</param>
/// <param name="x">x 시작 인덱스</param>
/// <param name="y">y 시작 인덱스</param>
void MakeColoredPaper2::CheckColoredPapers(int** arr, int n, int x, int y)
{
	if (IsAllSame(arr, n, x, y))
	{
		std::cout << arr[y][x];
		return;
	}
	else
	{
		std::cout << 'X';
	}

	int curSize{ n / 2 };
	CheckColoredPapers(arr, curSize, x, y);
	CheckColoredPapers(arr, curSize, x + curSize, y);
	CheckColoredPapers(arr, curSize, x, y + curSize);
	CheckColoredPapers(arr, curSize, x + curSize, y + curSize);
}

/// <summary>
/// 주어진 배열의 범위 내의 색상이 모두 동일한지 여부를 반환한다.
/// </summary>
/// <param name="arr">배열</param>
/// <param name="n">영역의 크기</param>
/// <param name="x">x 시작 인덱스</param>
/// <param name="y">y 시작 인덱스</param>
/// <returns>모든 생상이 동일한지 여부</returns>
bool MakeColoredPaper2::IsAllSame(int** arr, int n, int x, int y)
{
	int val{ arr[y][x] };
	for (int i = y; i < y + n; i++)
	{
		for (int j = x; j < x + n; j++)
		{
			if (arr[i][j] != val)
			{
				return false;
			}
		}
	}
	return true;
}

 


실행 결과 Success(100)

 

※ 이전 문제를 재귀적으로 처리했다면 더 쉽게 풀 수 있다.


 

NadanKim/CodingTest_JUNGOL: JUNGOL 코딩 테스트를 위한 저장소 (github.com)

 

NadanKim/CodingTest_JUNGOL

JUNGOL 코딩 테스트를 위한 저장소. Contribute to NadanKim/CodingTest_JUNGOL development by creating an account on GitHub.

github.com