상세 컨텐츠

본문 제목

12100. 2048 (Easy) GOLD II (C++)

알고리즘/백준

by 아리따운노을 2020. 5. 11. 23:48

본문

https://www.acmicpc.net/problem/12100

 

12100번: 2048 (Easy)

첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2보다 크거나 같고, 1024보다 작거나 같은 2의 제곱꼴이다. 블록은 적어도 하나 주어진다.

www.acmicpc.net

 

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <iostream>
#include <vector>
#include <queue>
 
using namespace std;
 
int MAP[20][20],temp[20][20], ans,n;
int mx[] = {-1,1,0,0}, my[] = {0,0,-1,1}; //u,d,l,r
vector<int> Vdir;
 
int check()
{
    queue<int> q;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            temp[i][j] = MAP[i][j];
    for(int i=0;i<5;i++)
    {
        int dir = Vdir[i];
        switch (dir)
        {
        case 0//u
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(temp[j][i] != 0)
                    {
                        q.push(temp[j][i]);
                        temp[j][i] = 0;
                    }
                }
                int idx = 0;
                while(q.size() > 1)
                {
                    temp[idx][i] = q.front();
 
                    q.pop();
                    if(temp[idx][i] == q.front())
                    {
                        q.pop();
                        temp[idx][i] *= 2;
                    }
                    idx++;
                }
                if(!q.empty()){
                    temp[idx][i] = q.front();
                    q.pop();
                }
            }
            break;
 
        case 1//d
            for(int i=0;i<n;i++)
            {
                for(int j= n - 1;j>=0;j--)
                {
                    if(temp[j][i] != 0)
                    {
                        q.push(temp[j][i]);
                        temp[j][i] = 0;
                    }
                }
                int idx = n - 1;
                while(q.size() > 1)
                {
                    temp[idx][i] = q.front();
 
                    q.pop();
                    if(temp[idx][i] == q.front())
                    {
                        q.pop();
                        temp[idx][i] *= 2;
                    }
                    idx--;
                }
                if(!q.empty()){
                    temp[idx][i] = q.front();
                    q.pop();
                }
            }
 
            break;
        case 2//left
            for(int i=0;i<n;i++)
            {
                for(int j= 0;j<n;j++)
                {
                    if(temp[i][j] != 0)
                    {
                        q.push(temp[i][j]);
                        temp[i][j] = 0;
                    }
                }
                int idx = 0;
                while(q.size() > 1)
                {
                    temp[i][idx] = q.front();
 
                    q.pop();
                    if(temp[i][idx] == q.front())
                    {
                        q.pop();
                        temp[i][idx] *= 2;
                    }
                    idx++;
                }
                if(!q.empty()){
                    temp[i][idx] = q.front();
                    q.pop();
                }
            }
 
 
            break;
        case 3//right
            for(int i=0;i<n;i++)
            {
                for(int j= n-1;j>=0;j--)
                {
                    if(temp[i][j] != 0)
                    {
                        q.push(temp[i][j]);
                        temp[i][j] = 0;
                    }
                }
                int idx = 0;
                while(q.size() > 1)
                {
                    temp[i][idx] = q.front();
 
                    q.pop();
                    if(temp[i][idx] == q.front())
                    {
                        q.pop();
                        temp[i][idx] *= 2;
                    }
                    idx++;
                }
                if(!q.empty()){
                    temp[i][idx] = q.front();
                    q.pop();
                }
 
            }
 
            break;
 
        }
    }
    int ret = 0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(temp[i][j] > ret)
                ret = temp[i][j];
 
    return ret;
}
int solve()
{
    int ret = 0;
    for(int aa=0;aa<4;aa++)
    {
        Vdir.push_back(aa);
        for(int bb=0;bb<4;bb++)
        {
            Vdir.push_back(bb);
            for(int cc =0;cc<4;cc++)
            {
                Vdir.push_back(cc);
                for(int dd = 0; dd<4;dd++)
                {
                    Vdir.push_back(dd);
                    for(int ee=0;ee<4;ee++)
                    {
                        Vdir.push_back(ee);
                        int a = check();
                        ret = ret > a ? ret : a;
                        Vdir.pop_back();
                    }
                    Vdir.pop_back();
                }
                Vdir.pop_back();
            }
            Vdir.pop_back();
        }
        Vdir.pop_back();
    }
 
    return ret;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>MAP[i][j];
    cout<<solve();
    return 0;
}
 
cs

음... 조금 방향 설정하는게 너저분하긴 하다.

5번 돌렸을 때 최대값을 찾는 것인데 횟수가 늘어날수록 크기가 커지면 커졌지 줄어들지는 않으니 5번 다 돌린다음에 최대값을 찾으면 된다. 그래서 중간에 확인하는 과정이 필요없다.

 

벡터에 5개 넣는것은 이제 재귀로도 짤 수 있었는데 for문 쓰는게 직관적이어서 저렇게 했다.

그런데 너저분하네

 

돌리는 과정은 이렇다.

1. 먼저 원조 배열을 복사한 배열을 생성한다.

2. 5방향으로 돌린다.

 

돌리는 매커니즘은 위쪽 방향만 설명하겠다. 다른 방향은 다 똑같은 매커니즘으로 하면 된다.

위쪽으로 움직이는 것은 열을 움직이는 것이기 때문에 각 열의 값들을 queue에 집어 넣으면서 0으로 바꿔준다.

 

맨 위부터 queue에 front값을 넣어주는데 같은 숫자 2개일 때 합쳐진다고 했으므로 

이 때 다음 queue의 front값과 동일하면 현재 값을 X2 해주고 queue를 한 번더 pop 해준다.

 

위 과정을 모든 열에 대해서 실행한다. 

다른 방향도 위와 같은 매커니즘으로 돌리면 된다.

 

이걸 돌리고 최대값을 찾아 답을 구해주면 된다.

 

 

 

 

관련글 더보기

댓글 영역