-

[삼성SW테스트] 백준 12100번 - 2048 (Easy) (정답률 23%) 본문

1-1. 삼성 SW 테스트

[삼성SW테스트] 백준 12100번 - 2048 (Easy) (정답률 23%)

asdklfjlasdlfkj 2020. 1. 15. 12:33

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

 

12100번: 2048 (Easy)

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

www.acmicpc.net

삼성 SW테스트 기출문제다. (유형: 시뮬레이션 + DFS)

0번부터 최대 5번 판을 기울여 만들 수 있는 수 중 가장 큰 수를 구하는 문제다.

어차피 기울이면 이전과 같거나 더 큰 수가 나올 수 있기 때문에 5번 모두 기울인 경우를 고려해보면 된다.

 

다음 DFS로 넘어가고나서 바로 아래줄에 다음 회전경우를 위해 판을 재초기화 해주는 것이 중요하고,

회전 함수에서는 한 줄씩, 각 방향의 끝에서부터 큐에 0이 아닌 숫자를 담아준 뒤, 판의 해당 줄을 0으로 초기화해주고 인덱스 변수를 하나 잡아 순차적으로 조건에 맞게 넣어주면 되는 문제였다.

 

아래는 소스코드 (4ms)

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
#include <iostream>
#include <queue>
using namespace std;
const int MAX = 20;
int N;
int board[MAX][MAX];
int maxBlock;
void shift(int type)
{
    queue<int> q;
    //숫자들을 큐에 집어놓고 각 행의
    //해당방향 끝에서부터 숫자를 넣기 시작
    switch (type)
    {
        //왼쪽
    case 0:
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                if (board[i][j])
                    q.push(board[i][j]);
                board[i][j] = 0;
            }
            int idx = 0;
            while (!q.empty())
            {
                int data = q.front();
                q.pop();
                if (board[i][idx] == 0)
                    board[i][idx] = data;
                else if (board[i][idx] == data)
                {
                    board[i][idx] *= 2;
                    //시중에 나와있는 게임과 달리 여러번 합쳐지지 않는다
                    idx++;
                }
                else
                {
                    idx++;
                    board[i][idx] = data;
                }
            }
        }
        break;
        //오른쪽
    case 1:
        for (int i = 0; i < N; i++)
        {
            for (int j = N - 1; j >= 0; j--)
            {
                if (board[i][j])
                    q.push(board[i][j]);
                board[i][j] = 0;
            }
            int idx = N - 1;
            while (!q.empty())
            {
                int data = q.front();
                q.pop();
                if (board[i][idx] == 0)
                    board[i][idx] = data;
                else if (board[i][idx] == data)
                {
                    board[i][idx] *= 2;
                    idx--;
                }
                else
                {
                    idx--;
                    board[i][idx] = data;
                }
            }
        }
        break;
        //위쪽
    case 2:
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                if (board[j][i])
                    q.push(board[j][i]);
                board[j][i] = 0;
            }
            int idx = 0;
            while (!q.empty())
            {
                int data = q.front();
                q.pop();
                if (board[idx][i] == 0)
                    board[idx][i] = data;
                else if (board[idx][i] == data)
                {
                    board[idx][i] *= 2;
                    idx++;
                }
                else
                {
                    idx++;
                    board[idx][i] = data;
                }
            }
        }
        break;
        //아래쪽
    case 3:
        for (int i = 0; i < N; i++)
        {
            for (int j = N - 1; j >= 0; j--)
            {
                if (board[j][i])
                    q.push(board[j][i]);
                board[j][i] = 0;
            }
            int idx = N - 1;
            while (!q.empty())
            {
                int data = q.front();
                q.pop();
                if (board[idx][i] == 0)
                    board[idx][i] = data;
                else if (board[idx][i] == data)
                {
                    board[idx][i] *= 2;
                    idx--;
                }
                else
                {
                    idx--;
                    board[idx][i] = data;
                }
            }
        }
        break;
    }
}
void DFS(int cnt)
{
    if (cnt == 5)
    {
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                maxBlock = max(maxBlock, board[i][j]);
        return;
    }
    int copyBoard[MAX][MAX];
    //현 보드상태 저장해놓고
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            copyBoard[i][j] = board[i][j];
    for (int i = 0; i < 4; i++)
    {
        shift(i);
        DFS(cnt + 1);
        //저장해놓은 보드상태로 원상복구
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                board[i][j] = copyBoard[i][j];
    }
}
int main(void)
{
    cin >> N;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            cin >> board[i][j];
    DFS(0);
    cout << maxBlock << endl;
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

Comments