2 분 소요

[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인 경우, 같은 경우, 다른 경우로 나누어서 뿌려준다.

    Untitled

카테고리:

업데이트: