작심삼일

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

스터디/코테

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

yun_s 2021. 11. 24. 18:06
728x90
반응형

문제 링크: https://www.acmicpc.net/problem/1780


문제

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

  1. 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
  2. (1)이 아닌 경우에는 종이를 같은 크기의 종이 9개로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.

이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구해내는 프로그램을 작성하시오.


입력

첫째 줄에 N(1 ≤ N ≤ 37, N은 3k 꼴)이 주어진다. 다음 N개의 줄에는 N개의 정수로 행렬이 주어진다.


출력

첫째 줄에 -1로만 채워진 종이의 개수를, 둘째 줄에 0으로만 채워진 종이의 개수를, 셋째 줄에 1로만 채워진 종이의 개수를 출력한다.


내 풀이

주어진 3의 제곱수, N의 길이의 정사각형의 수가 모두 같은 수인지 확인한 후 그렇지 않으면 N/3의 정사각형을 확인하는 것을 반복한다.


코드

#include <iostream>
#include <algorithm>
#define len 3*3*3*3*3*3*3
using namespace std;

int N, paper[len][len], temp, total[3];

int small(int s_y, int s_x, int s) {
	temp = paper[s_y][s_x];
	for (int y = s_y; y < s_y + s; y++) {
		for (int x = s_x; x < s_x + s; x++) {
			if (paper[y][x] != temp)	return 1;
		}
	}

	if (temp == -1)	total[0]++;
	else if (temp == 0)	total[1]++;
	else total[2]++;

	return 0;
}

int split(int s_y, int s_x, int s) {
	for (int y = 0; y < 3; y++) {
		for (int x = 0; x < 3; x++) {
			if (small(s_y + s*y, s_x + s*x, s)) {
				split(s_y + s*y, s_x + s*x, s / 3);
			}
		}
	}
	return 0;
}

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

	for (int y = 0; y < N; y++) {
		for (int x = 0; x < N; x++) {
			scanf("%d", &paper[y][x]);
		}
	}

	if (small(0, 0, N)) {
		split(0, 0, N / 3);
	}

	for (int t = 0; t < 3; t++)
		printf("%d\n", total[t]);

	return 0;
}

 

728x90
반응형
Comments