본문 바로가기

알고리즘/Algospot

6.5 문제: 게임판 덮기 (문제 ID: BOARDCOVER, 난이도: 하)


★★★★★다시 풀어볼 문제★★★★★


알고리즘 문제해결전략 1권

6.5 문제: 게임판 덮기 (문제 ID: BOARDCOVER, 난이도: 하)


완전탐색 문제


첫번째 코드는 시간상 오류가 나는 코드이다.

내가 보기에 슈퍼컴퓨터라면 정답은 나올 것 같다;;

나름 중복되는 경우의 수를 지우기 위해 재귀함수의 for문을 건드렸지만, 아주 미세한 차이만을 나타냈을 뿐이었다.

일단 나름 책에서의 첫문제를 적용해서 풀려고 노력은 했다는 점은 만족한다.


정답 코드는 일단 for문에서 경우의 수를 줄이려고 한 것이 아니라는 점이 좋았다.

나 같은 경우에는 항상 for문을 복잡하게 만들어서 경우의 수를 줄이려고 하는 습관이 있었는데 그것을 깰 수 있었다.

내가 실수한 점은 진짜 무식하게 모든 경우를 돌려서 블록을 맞추려고 했던 점이고,

정답 코드는 왼쪽 상단부터 블록을 맞춰가면서 푼다는 점이었다.

그렇기 때문에 항상 왼쪽과 위의 칸은 맞춰져 있다는 가정 <- 이 가정도 굉장히 중요했다. 이 때문에 내가 첫번째 실수했던 코드에서

블록을 채우는 배열함수를 바꿔야 한다는 것을 깨달았다.

그래서 오히려 경우의 수를 대폭 줄일 수 있었다. (기존의 내 코드에 비해서)

또한 블록이 3칸짜리를 채우는 것이기 때문에 빈칸이 3의 배수로 존재해야 한다는 점.

간과하기 쉽지만 간과해서는 안되는 점이었다.


난이도 '하' 라고 주어졌지만 은근히 생각할 게 많은 문제인 것 같다...

나름 N-Queen 같은 문제는 쉽게 풀었는데... 알고리즘은 성향에 따라 본인이 느끼는 수준이 천차만별인 것 같다.. 특히 나같은 초보일 수록..




실수 코드


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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include<iostream>
 
using namespace std;
int H, W;
char map[21][21];
 
int dx[4][2= { { -1,0},{-1,0},{1,0},{1,0} };
int dy[4][2= { { 0,1},{0,-1},{0,1},{0,-1} };
int ans;
bool isCovered[21][21];
void print()
{
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            cout << isCovered[i][j] << " ";
 
        }
        cout << endl;
 
    }
 
    cout << "-------------------------------" << endl;
}
void cover(int x, int y)
{
    bool finished = true;
 
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            if (!isCovered[i][j])
            {
                finished = false;
                break;
            }
        }
 
        if (!finished)
        {
            break;
        }
    }
 
 
    if (finished)
    {
        ans += 1;
        return;
    }
 
    for (int i = x; i < H; i++)
    {
        if (x != i)
        {
            for (int j = 0; j < W; j++)
            {
                if (map[i][j] == '.' && !isCovered[i][j])
                {
                    for (int d = 0; d < 4; d++)
                    {
                        int x0 = i + dx[d][0];
                        int y0 = j + dy[d][0];
                        int x1 = i + dx[d][1];
                        int y1 = j + dy[d][1];
                        if (map[x0][y0] == '.' && map[x1][y1] == '.' && x0 >= 0 && y0 >= 0 && x0 < H && y0 < W && x1 >= 0 && y1 >= 0 && x1 < H && y1 < W && !isCovered[x0][y0] && !isCovered[x1][y1])
                        {
                            isCovered[i][j] = true;
                            isCovered[x0][y0] = true;
                            isCovered[x1][y1] = true;
                            print();
                            cover(i, j);
                            isCovered[i][j] = false;
                            isCovered[x0][y0] = false;
                            isCovered[x1][y1] = false;
                            print();
                        }
 
                    }
                }
            }
        }
        else
        {
            for (int j = y; j < W; j++)
            {
                if (map[i][j] == '.' && !isCovered[i][j])
                {
                    for (int d = 0; d < 4; d++)
                    {
                        int x0 = i + dx[d][0];
                        int y0 = j + dy[d][0];
                        int x1 = i + dx[d][1];
                        int y1 = j + dy[d][1];
                        if (map[x0][y0] == '.' && map[x1][y1] == '.' && x0 >= 0 && y0 >= 0 && x0 < H && y0 < W && x1 >= 0 && y1 >= 0 && x1 < H && y1 < W && !isCovered[x0][y0] && !isCovered[x1][y1])
                        {
                            isCovered[i][j] = true;
                            isCovered[x0][y0] = true;
                            isCovered[x1][y1] = true;
                            print();
                            cover(i, j);
                            isCovered[i][j] = false;
                            isCovered[x0][y0] = false;
                            isCovered[x1][y1] = false;
                            print();
                        }
 
                    }
                }
            }
        }
    }
    return;
}
 
 
 
int main()
{
    freopen("input.txt""r", stdin);
 
    int tc;
    cin >> tc;
 
    for (int t = 1; t <= tc; t++)
    {
        //맵 초기화
        for (int i = 0; i < 21; i++)
        {
            for (int j = 0; j < 21; j++)
            {
                map[i][j] = '#';
                isCovered[i][j] = false;
            }
        }
 
        ans = 0;
 
        cin >> H >> W;
 
        for (int i = 0; i < H; i++)
        {
            for (int j = 0; j < W; j++)
            {
                cin >> map[i][j];
                if (map[i][j] == '#')
                {
                    isCovered[i][j] = true;
                }
            }
        }
 
        cover(00);
 
        cout << ans << endl;
 
 
    }
 
    return 0;
}
cs




정답 코드


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
138
139
140
141
#include<iostream>
 
using namespace std;
int H, W;
char map[21][21];
 
int dx[4][2= { { 1,1},{1,1},{1,0},{1,0} };
int dy[4][2= { { 0,-1},{0,1},{1,1},{0,1} };
int ans;
int n_num;
int n;
bool isCovered[21][21];
void print()            //진행과정 디버깅 용
{
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            cout << isCovered[i][j] << " ";
 
        }
        cout << endl;
 
    }
 
    cout << "-------------------------------" << endl;
}
void cover()
{
    bool finished = true;
    int x = -1;
    int y = -1;
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            if (map[i][j]=='.' && !isCovered[i][j])
            {
                x = i;
                y = j;
                finished = false;
                break;
            }
        }
 
        if (!finished)
        {
            break;
        }
    }
 
 
    if (finished)
    {
        ans += 1;
        return;
    }
 
 
    for (int d = 0; d < 4; d++)
    {
        int x0 = x + dx[d][0];
        int y0 = y + dy[d][0];
        int x1 = x + dx[d][1];
        int y1 = y + dy[d][1];
        if (map[x0][y0] == '.' && map[x1][y1] == '.' && x0 >= 0 && y0 >= 0 && x0 < H && y0 < W && x1 >= 0 && y1 >= 0 && x1 < H && y1 < W && !isCovered[x0][y0] && !isCovered[x1][y1])
        {
            isCovered[x][y] = true;
            isCovered[x0][y0] = true;
            isCovered[x1][y1] = true;
            //print();
            cover();
            isCovered[x][y] = false;
            isCovered[x0][y0] = false;
            isCovered[x1][y1] = false;
            //print();
        }
    }
 
    return;
}
 
 
 
int main()
{
    //freopen("input.txt", "r", stdin);
 
    int tc;
    cin >> tc;
 
    for (int t = 1; t <= tc; t++)
    {
        //맵 초기화
        for (int i = 0; i < 21; i++)
        {
            for (int j = 0; j < 21; j++)
            {
                map[i][j] = '#';
                isCovered[i][j] = false;
            }
        }
 
        ans = 0;
        n_num = 0;
 
        cin >> H >> W;
 
        for (int i = 0; i < H; i++)
        {
            for (int j = 0; j < W; j++)
            {
                cin >> map[i][j];
                if (map[i][j] == '#')
                {
                    isCovered[i][j] = true;
                }
                else if (map[i][j] = '.')
                {
                    n_num += 1;
                }
            }
        }
 
        if (n_num % 3 == 0)
        {
            cover();
        }
        else
        {
            ans = 0;
        }
        
 
        cout << ans << endl;
 
 
    }
 
    return 0;
}
cs


반응형