Post

[BOJ] 17136 - 색종이 붙이기

문제 링크

스포를 당해서 쉽게 풀었던 문제다.
어줍짢게 시간복잡도를 줄인다고 최선의 경우의 수를 찾아 그리디하게 접근하면 틀리는 문제(라고 한다. 그렇게 들어서 그리디하지 않은 방법으로만 시도했다.)
일단 현재 시점에서 붙일 수 있는 모든 경우의 수를 시도해주었다.

소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <algorithm>
using namespace std;

int paper[15][15], color[6], ans = 99;

bool is_in_range(int x, int y) {
	return x >= 0 && x < 10 && y >= 0 && y < 10;
}

bool is_attachable(int x, int y, int size) {
	if (color[size] >= 5) return false;
	for (int i = 0; i < size; i++)
		for (int j = 0; j < size; j++)
			if (!paper[x + i][y + j])
				return false;
	return true;
}

void attach(int x, int y, int size) {
	for (int i = 0; i < size; i++)
		for (int j = 0; j < size; j++)
			paper[x + i][y + j] = 0;
}

void remove(int x, int y, int size) {
	for (int i = 0; i < size; i++)
		for (int j = 0; j < size; j++)
			paper[x + i][y + j] = 1;
}

void go(int x, int y, int count) {
	for (int i = 1; i <= 5; i++) {
		if (!is_in_range(x + i - 1, y + i - 1) || !is_attachable(x, y, i))
			continue;
		attach(x, y, i);
		color[i]++;
		bool ck = true;
		for (int r = x; ck && r < 10; r++)
			for (int c = 0; ck && c < 10; c++)
				if (paper[r][c]) {
					ck = false;
					go(r, c, count + 1);
				}

		if (ck) ans = min(ans, count + 1);
		remove(x, y, i);
		color[i]--;
	}
}

int main(void) {
	for (int i = 0; i < 10; i++)
		for (int j = 0; j < 10; j++)
			scanf("%d", paper[i] + j);

	for (int i = 0; i < 10; i++)
		for (int j = 0; j < 10; j++)
			if (paper[i][j]) {
				go(i, j, 0);
				printf("%d", ans == 99 ? -1 : ans);
				return 0;
			}

	printf("%d", 0);
	return 0;
}
This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.