[BOJ] C++ 2630 "색종이 만들기" 문제 풀이 _ nov

반응형
반응형

#INFO

난이도 : SILVER3

알고리즘 : 재귀

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

 

2630번: 색종이 만들기

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

www.acmicpc.net


#SOLVE

색종이 배열 전체를 탐색하여 모든 원소가 1또는 0으로 같은지 판별 후 다르다면 4가지 구역으로 나누어 재귀를 수행하면 되는 간단한 문제이다.

 

색종이의 크기 n과 y, x 좌표를 인수로 받는 recur 함수를 선언한다.

void recur(int n, int y, int x)

base condition (모든 재귀함수가 수렴하는 값) 은 1로 설정하고 색종이 배열의 원소가 1인 경우에는 blueCnt(파란 색종이의 수)를 1 증가, 배열의 원소가 0인 경우에는 whiteCnt(하얀 색종이의 수)를 1 증가시킨 후 리턴한다.

	//base condition
	if(n == 1){ 
		if(paper[y][x] == 1){
			blueCnt++;
		}
		else{
			whiteCnt++;
		}
		return;
	}

모든 배열의 원소가 같은 값으로 저장되어 있는 지 배열 전체를 반복문을 돌려서 확인한다.

	bool blue = true, white = true;
	for(int i = y; i < y + n; i++){
		for(int j = x; j < x + n; j++){
			if(paper[i][j] == 1) white = false;
			else if(paper[i][j] == 0) blue = false;
		}
	}

만약 blue가 true라면 해당 구역의 모든 원소가 0으로 되어 있다는 뜻 이기에 blueCnt를 1증가시키고, white가 true라면 해당 구역의 모든 원소가 1로 되어 있다는 뜻 이므로 whiteCnt를 1증가시킨다.

blue , white 변수가 모두 false라면 모두 같은 색으로 칠해져 있지 않다는 뜻 이기에 4가지 구역으로 나누어 함수를 재귀적으로 호출한다.

	if(blue){
		blueCnt++;
		return;
	}
	else if(white){
		whiteCnt++;
		return;
	}
	else {
		recur(n/2, y, x);
		recur(n/2, y, x+ n/2);
		recur(n/2, y + n/2, x);
		recur(n/2, y + n/2, x + n/2);
	}

#CODE

#include <bits/stdc++.h>
using namespace std;
int paper[129][129];
int n;
int blueCnt = 0;
int whiteCnt = 0;
void recur(int n, int y, int x){
	//base condition
	if(n == 1){ 
		if(paper[y][x] == 1){
			blueCnt++;
		}
		else{
			whiteCnt++;
		}
		return;
	}
	
	bool blue = true, white = true;
	for(int i = y; i < y + n; i++){
		for(int j = x; j < x + n; j++){
			if(paper[i][j] == 1) white = false;
			else if(paper[i][j] == 0) blue = false;
		}
	}		
	
	if(blue){
		blueCnt++;
		return;
	}
	else if(white){
		whiteCnt++;
		return;
	}
	else {
		recur(n/2, y, x);
		recur(n/2, y, x+ n/2);
		recur(n/2, y + n/2, x);
		recur(n/2, y + n/2, x + n/2);
	}
	return;
}

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
	cin >> n;
	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)
			cin >> paper[i][j];
	recur(n, 0, 0);
	cout << whiteCnt << '\n' << blueCnt << '\n';
	return 0;
}
반응형

댓글

Designed by JB FACTORY