[백준 12094번] 2048 (Hard)

2022. 1. 8. 00:38·알고리즘 문제풀이/백준
반응형

문제 링크: https://www.acmicpc.net/problem/12094

 

12094번: 2048 (Hard)

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

www.acmicpc.net

<문제 풀이> 백트랙킹

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

 

12100번: 2048 (Easy)

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

www.acmicpc.net

2048 Easy 문제에서 백트랙킹이 추가된 문제이다.

 

1. 이동 후 항상 변화가 있어야 한다. (이동 후 배열의 값이 바뀌었는지 체크)

2 4 8

2 4 8 

2 4 8

에서 left를 하면

2 4 8

2 4 8

2 4 8

변화가 없는 상태에서 계속 연산을 해봤자 의미가 없다. 

-> 최대 k 번까지 이동했을 때 최댓값을 구하고 싶은 거니깐 항상 변화가 있어야 한다.

 

2. k번 이동했을 때 현재 배열의 값으로 10번까지 이동해서 만들 수 있는 최댓값이 지금 까지 갱신한 최댓값 이하이면  더 이상 진행하지 않는다.

1번 이동했을 때 현재 배열의 값의 최대값이 2라면

10번 이동했을 때 현재 배열의 최댓값으로 만들 수 있는 수는 2048이다.

2 * 2 ^ (10 - 1) = 1024  -> ( 현재 배열의 값의 최대값 * 2^(10 - k) ) 

그런데 지금까지 갱신한 최댓값이 4096이라면

아무리 최고의 상황이 나오더라도 10번까지 이동해서 4096을 만들 수 없다

 

 

<C++ 소스 코드>

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
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
#include <cmath>
#include <deque>
#include <cstdlib>
using namespace std;
 
int N;
int board[20][20];
bool visited[20][20];
int res = 0;
int max_res = 0;
void printBoard() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cout << board[i][j] << ' ';
        }
        cout << '\n';
    }
    cout << "\n\n";
}
 
void rotate() {
    int temp[20][20];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            temp[i][j] = board[i][j];
        }
    }
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            board[i][j] = temp[N - j - 1][i];
        }
    }
}
 
 
void left() {
    for (int i = 0; i < N; i++) {
        int moved[20] = { 0, };
        bool combined[20] = { 0, };
        int idx = 0;
        for (int j = 0; j < N; j++) {
            if (board[i][j] == 0) continue;
            if (moved[idx] == 0) {
                moved[idx] = board[i][j];
            }
            else if (moved[idx] && combined[idx]) {
                moved[++idx] = board[i][j];
            }
            else if (moved[idx] == board[i][j]){
                moved[idx] *= 2;
                combined[idx++] = true;
           
            }
            else {
                moved[++idx] = board[i][j];
            }
 
            
        }
        for (int j = 0; j < N; j++) {
            board[i][j] = moved[j];
        }
    }
}
 
void up() {
    rotate();
    rotate();
    rotate();
    left();
    rotate();
}
void right() {
    rotate();
    rotate();
    left();
    rotate();
    rotate();
 
}
 
void down() {
    rotate();
    left();
    rotate();
    rotate();
    rotate();
}
 
void tempToBoard(int temp[][20]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            board[i][j] = temp[i][j];
        }
    }
}
 
bool isChanged(int arr1[][20], int arr2[][20]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (arr1[i][j] != arr2[i][j]) return true;
        }
    }
    return false;
}
 
void dfs(int k) {
    int temp[20][20];
    int cur_max = 0;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            temp[i][j] = board[i][j];
            if (board[i][j] >= cur_max) cur_max = board[i][j];
        }
    }
    res = max(res, cur_max);
 
    if (k == 10) return;
    if (cur_max * 1 << (10 - k) <= res) return;
 
    left();
    if (isChanged(temp, board)) {
        dfs(k + 1);
        tempToBoard(temp);
    }
    right();
    if (isChanged(temp, board)) {
        dfs(k + 1);
        tempToBoard(temp);
    }
    up();
    if (isChanged(temp, board)) {
        dfs(k + 1);
        tempToBoard(temp);
    }
    down();
    if (isChanged(temp, board)) {
        dfs(k + 1);
        tempToBoard(temp);
    }
 
 
 
 
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> board[i][j];
            if (board[i][j] >= max_res) max_res = board[i][j];
        }
    }
    
    dfs(0);
    cout << res;
   
    return 0;
}
 
 
Colored by Color Scripter
cs

 

반응형
저작자표시 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 11559번] Puyo Puyo  (0) 2022.01.13
[백준 15686번] 치킨 배달  (0) 2022.01.09
[백준 12100번] 2048(Easy)  (0) 2022.01.05
[백준 18808번] 스티커 붙이기  (0) 2022.01.05
[백준 2636번] 치즈  (0) 2022.01.05
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 11559번] Puyo Puyo
  • [백준 15686번] 치킨 배달
  • [백준 12100번] 2048(Easy)
  • [백준 18808번] 스티커 붙이기
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (199)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (1)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Kotlin
    콘솔
    백트랙킹
    코틀린
    C
    C++
    백준
    알고리즘
    dfs
    다이나믹 프로그래밍
    콘솔 테트리스 게임
    dp
    BFS
    그리디
    자료구조
    시뮬레이션
    코틀린을 활용한 안드로이드 프로그래밍
    구현
    그래프
    우선순위 큐
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 12094번] 2048 (Hard)
상단으로

티스토리툴바