[C++] 2630: 색종이 만들기

우나·2022년 12월 15일

백준

목록 보기
14/16

정답 코드

#include <iostream>
#include <queue>
using namespace std;

int arr[129][129];
int N, blue{ 0 }, white{ 0 };

int isALL(int start_x, int start_y, int end_x, int end_y) {
	int color = arr[start_x][start_y];
	for (int i = start_x; i <= end_x; i++) {
		for (int j = start_y; j <= end_y; j++) {
			if (arr[i][j] != color) return -1;
		}
	}
	return color;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	int num;
	cin >> N;

	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cin >> num;
			arr[i][j] = num;
		}
	}

	if (isALL(1, 1, N, N) != -1) isALL(1, 1, N, N) == 0 ? white++ : blue++;
	else {

		// 시작 좌표 & 끝 좌표 저장
		queue<pair<pair<int, int>, pair<int, int>>> Q;
		Q.push(make_pair(make_pair(1, 1), make_pair(N / 2, N / 2)));
		Q.push(make_pair(make_pair(N / 2 + 1, 1), make_pair(N, N / 2)));
		Q.push(make_pair(make_pair(1, N / 2 + 1), make_pair(N / 2, N)));
		Q.push(make_pair(make_pair(N / 2 + 1, N / 2 + 1), make_pair(N, N)));

		// Q에서 하나씩 꺼내서 검증
		while (!Q.empty()) {
			pair<pair<int, int>, pair<int, int>> cur = Q.front();
			Q.pop();

			int s_x = cur.first.first;
			int s_y = cur.first.second;
			int e_x = cur.second.first;
			int e_y = cur.second.second;

			/*cout << "start : " << s_x << " " << s_y << "\n"
				<< "end : " << e_x << " " << e_y << "\n";*/

			if (isALL(s_x, s_y, e_x, e_y) != -1) isALL(s_x, s_y, e_x, e_y) == 0 ? white++ : blue++;
			else {
				int new_x = (e_x - s_x - 1) / 2 + s_x;
				int new_y = (e_y - s_y - 1) / 2 + s_y;

				Q.push(make_pair(make_pair(s_x, s_y), make_pair(new_x, new_y)));
				Q.push(make_pair(make_pair(new_x + 1, s_y), make_pair(e_x, new_y)));
				Q.push(make_pair(make_pair(s_x, new_y + 1), make_pair(new_x, e_y)));
				Q.push(make_pair(make_pair(new_x + 1, new_y + 1), make_pair(e_x, e_y)));
			}
		}
	}
	cout << white << "\n" << blue;

}

코드 분석

int isALL(int start_x, int start_y, int end_x, int end_y) {
	int color = arr[start_x][start_y];
	for (int i = start_x; i <= end_x; i++) {
		for (int j = start_y; j <= end_y; j++) {
			if (arr[i][j] != color) return -1;
		}
	}
	return color;
}

모든 칸의 색상이 같은지 판별하는 함수
같으면 색상을 반환하고, 다르면 -1 반환

queue<pair<pair<int, int>, pair<int, int>>> Q;
		Q.push(make_pair(make_pair(1, 1), make_pair(N / 2, N / 2)));
		Q.push(make_pair(make_pair(N / 2 + 1, 1), make_pair(N, N / 2)));
		Q.push(make_pair(make_pair(1, N / 2 + 1), make_pair(N / 2, N)));
		Q.push(make_pair(make_pair(N / 2 + 1, N / 2 + 1), make_pair(N, N)));

큐에 네 영역의 탐색 시작 좌표, 끝 좌표 저장

		while (!Q.empty()) {
			pair<pair<int, int>, pair<int, int>> cur = Q.front();
			Q.pop();

			int s_x = cur.first.first;
			int s_y = cur.first.second;
			int e_x = cur.second.first;
			int e_y = cur.second.second;

			/*cout << "start : " << s_x << " " << s_y << "\n"
				<< "end : " << e_x << " " << e_y << "\n";*/

			if (isALL(s_x, s_y, e_x, e_y) != -1) isALL(s_x, s_y, e_x, e_y) == 0 ? white++ : blue++;
			else {
				int new_x = (e_x - s_x - 1) / 2 + s_x;
				int new_y = (e_y - s_y - 1) / 2 + s_y;

				Q.push(make_pair(make_pair(s_x, s_y), make_pair(new_x, new_y)));
				Q.push(make_pair(make_pair(new_x + 1, s_y), make_pair(e_x, new_y)));
				Q.push(make_pair(make_pair(s_x, new_y + 1), make_pair(new_x, e_y)));
				Q.push(make_pair(make_pair(new_x + 1, new_y + 1), make_pair(e_x, e_y)));
			}
		}
	}

큐에서 하나씩 꺼내서 검사
isALL이 -1이면 영역을 나눠서 큐에 다시 push

0개의 댓글