Game Develop

[Algorithm]Baekjoon 17136번 :: 색종이 붙이기 본문

Algorithm/Baekjoon

[Algorithm]Baekjoon 17136번 :: 색종이 붙이기

MaxLevel 2024. 11. 3. 19:07

https://www.acmicpc.net/problem/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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <math.h>
#include <queue>
#include <functional>
#include <sstream>
#include <memory.h>
#include <deque>
#include <set>
#include <unordered_set>
 
using namespace std;
 
int arr[10][10= { 0 };
 
bool CanPlacePaper(int y, int x, int size)
{
    int maxY = y + size - 1;
    int maxX = x + size - 1;
 
    if (maxY >= 10return false;
    if (maxX >= 10return false;
 
    for (int i = y; i <= maxY; ++i)
    {
        for (int j = x; j <= maxX; ++j)
        {
            if (arr[i][j] == 0return false;
        }
    }
 
    return true;
}
 
void FillArrayRange(int y, int x, int sizeint num)
{
    int maxY = y + size - 1;
    int maxX = x + size - 1;
 
    for (int i = y; i <= maxY; ++i)
    {
        for (int j = x; j <= maxX; ++j)
        {
            arr[i][j] = num;
        }
    }
}
 
int answer = 0x3f3f3f3f;
int placeCount = 0;
int oneCount = 0;
int paperCounts[6= { 0,5,5,5,5,5 };
 
void DFS(int y, int x)
{
    if (oneCount == 0// 다붙였으면
    {
        answer = min(answer, placeCount);
        return;
    }
 
    if (x == 10)
    {
        x = 0;
        ++y;
 
        if (y == 10return;
    }
 
    if (placeCount >= answer) return;
 
    if (arr[y][x] == 1)
    {
        for (int i = 5; i >= 1--i)
        {
            if (CanPlacePaper(y, x, i) && paperCounts[i] > 0// 붙일수 있고, 해당크기 색종이도 아직 남아있으면
            {
                FillArrayRange(y, x, i, 0);
                ++placeCount;
                oneCount -= i * i;
                --paperCounts[i];
                
 
                DFS(y, x + 1);
 
                // 원상복구
                FillArrayRange(y, x, i, 1); 
                --placeCount;
                oneCount += i * i;
                ++paperCounts[i];
                
            }
        }
    }
    else
    {
        DFS(y, x + 1);
    }
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
 
    for (int i = 0; i < 10++i)
    {
        for (int j = 0; j < 10++j)
        {
            cin >> arr[i][j];
            
            if (arr[i][j] == 1++oneCount;
        }
    }
 
    DFS(00);
 
    if (answer == 0x3f3f3f3fcout << -1;
    else cout << answer;
}
 
 
cs

 

연습으로 풀어볼만한 백트래킹 완전탐색문제이다.

 

색종이를 붙일 수 있는곳마다 각 사이즈의 색종이를 전부 붙이는 시도를한다. 

물론 해당사이즈의 색종이를 붙일 수 있는지 검사 후, 붙여야 한다.

붙이고 탐색을 진행하고, 해당 탐색이 끝난후엔 다시 값들을 복귀시켜야 한다는걸 잊지말자.

 

붙일 수 없으면 좌표이동만 시행한다.

 

골드2문제치고는 좀 쉬운문제라 생각된다.