[백준 12100] 2048 (Easy)
[12100] 2048 (Easy)
Algorithm: dfs Type: 백준 link: https://www.acmicpc.net/problem/12100
문제
2048 게임은 4×4 크기의 보드에서 혼자 즐기는 재미있는 게임이다. 이 링크를 누르면 게임을 해볼 수 있다.
이 게임에서 한 번의 이동은 보드 위에 있는 전체 블록을 상하좌우 네 방향 중 하나로 이동시키는 것이다. 이때, 같은 값을 갖는 두 블록이 충돌하면 두 블록은 하나로 합쳐지게 된다. 한 번의 이동에서 이미 합쳐진 블록은 또 다른 블록과 다시 합쳐질 수 없다. (실제 게임에서는 이동을 한 번 할 때마다 블록이 추가되지만, 이 문제에서 블록이 추가되는 경우는 없다) … 생략
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int N;
int board[21][21];
int ans;
void input(){
cin >> N;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
cin >> board[i][j];
ans = max(ans, board[i][j]);
}
}
}
int findMax(){
int ret = 0;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
ret = max(ret, board[i][j]);
}
}
return ret;
}
void solve(int dir){
queue <int> q;
if(dir == 0){ //상
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 top = q.front(); q.pop();
if(board[idx][i] == 0){
board[idx][i] = top;
}else if(board[idx][i] == top){
board[idx++][i] = top*2;
}else{
board[++idx][i] = top;
}
}
}
}else if(dir == 1){ //하
for(int i = N-1; i >= 0; 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 top = q.front(); q.pop();
if(board[idx][i] == 0){
board[idx][i] = top;
}else if(board[idx][i] == top){
board[idx--][i] = top*2;
}else{
board[--idx][i] = top;
}
}
}
}else if(dir == 2){ //좌
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 top = q.front(); q.pop();
if(board[i][idx] == 0){
board[i][idx] = top;
}else if(board[i][idx] == top){
board[i][idx++] = top*2;
}else{
board[i][++idx] = top;
}
}
}
}else{ //우
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 top = q.front(); q.pop();
if(board[i][idx] == 0){
board[i][idx] = top;
}else if(board[i][idx] == top){
board[i][idx--] = top*2;
}else{
board[i][--idx] = top;
}
}
}
}
// print();
}
void dfs(int depth){
//기저 조건
if(depth == 5){
ans = max(ans, findMax());
return;
}
//board 저장
int temp_board[21][21];
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
temp_board[i][j] = board[i][j];
}
}
//모든 방향으로 탐색
for(int k=0; k<4; k++){
solve(k);
dfs(depth+1);
//원래 상태로 돌려놓기
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
board[i][j] = temp_board[i][j];
}
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
input();
dfs(0);
cout << ans << endl;
return 0;
}
-
문제 풀이
dfs로 풀었다.
깊이를 하나씩 더해 줘가면서 board를 업데이트 시켜준다.
depth가 5가 되면, 최대 값을 찾는다.
상하좌우를 모두 탐색하며 dfs를 도는데,
상의 예시를 들겠다.
한 줄씩 돌면서 큐에 넣어주고,
다 넣어준 다음 다시 그 줄에 뿌려주면 된다.
뿌려줄 때에는 0인 경우, 같은 경우, 다른 경우로 나누어서 뿌려준다.