블로그

[C++] 백준 1780 : 종이의 개수 본문

PS

[C++] 백준 1780 : 종이의 개수

왕방토 2023. 3. 5. 00:06
728x90

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

 

1780번: 종이의 개수

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수

www.acmicpc.net

 

 

divide and conquer

 

 

비슷한 문제:https://www.acmicpc.net/problem/1074

 

1074번: Z

한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을

www.acmicpc.net

/2냐 /3이냐의 차이만 있음

 

 

어.. 음...

분할정복은 기본적으로 재귀함수를 많이 사용하니까

재귀함수에서 return 조건을 잘 확인해 주는 게 중요할 것 같다

기본적인 문제라 더 할말이 없네..

#include <iostream>
using namespace std;

int map[2187][2187];
int zero_cnt, one_cnt, minus_cnt;
int didj[9][2] = {
	{0, 0}, {0, 1}, {0, 2},
	{1, 0}, {1, 1}, {1, 2},
	{2, 0}, {2, 1}, {2, 2}
};

void dq(int si, int sj, int len) {
	if (len < 0) return;

	int start = map[si][sj];
	bool divide = false;
	for (int i = si; i < si + len; i++) {
		if (divide) break;
		for (int j = sj; j < sj + len; j++) {
			if (map[i][j] != start) {
				divide = true;
				break;
			}
		}
	}

	if (divide) {
		int nl = len / 3;
		for (int k = 0; k < 9; k++) {
			dq(si + nl * didj[k][0], sj + nl * didj[k][1], nl);
		}
	}
	else {
		if (start == 0) zero_cnt++;
		else if (start == 1) one_cnt++;
		else minus_cnt++;
	}
}

int main() {
	int N;
	scanf("%d", &N);

	for (int i = 0; i < N; i++) {
		for(int j = 0; j<N; j++) {
			scanf("%d", &map[i][j]);
		}
	}

	dq(0, 0, N);
	printf("%d\n%d\n%d", minus_cnt, zero_cnt, one_cnt);
}

 

'PS' 카테고리의 다른 글

[C++] 백준 4256 : 트리  (0) 2023.03.05
[C++] 백준 2263 : 트리의 순회  (0) 2023.03.05
[C++] 백준 1080 : 행렬  (0) 2023.03.04
[C++] 백준 14226 : 이모티콘  (0) 2023.03.04
[C++] 백준 11052: 카드 구매하기  (0) 2023.02.26
Comments