Algorithm/baekjoon

2048

마닐라 2022. 3. 1. 23:31

📍 문제 설명

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

 

12100번: 2048 (Easy)

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

www.acmicpc.net

 

💡 접근

각 위치에서 4방향으로 모두 이동하게 재귀 호출하는 것까지는 문제가 없었는데

해당 방향으로 볼록을 이동시키는 부분에서 너무 어려웠다.

해당 부분은 타 블로그를 참고했다..

 

👩‍💻 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int n, m, v, e, k, r, answer, cnt, max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
    static int[] arr, dx = {1,0,-1,0}, dy = {0,-1,0,1};
    static long[] dp;
    static int[][] board, clone;
    static boolean[][][][] visited;
    static ArrayList<String> list;
    static TreeSet<Character> set;
    static StringBuilder sb;
    static StringTokenizer st;

    public static void main(String[] args) throws IOException {
        Main T = new Main();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(br.readLine());

        board = new int[n][n];
        for(int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < n; j++) {
                board[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        T.solution(0);
        System.out.println(answer);
    }

    //5번의 게임을 한다.
    private void solution(int L) {
        if(L == 5) {
            //최댓값 구하기
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    answer = Math.max(answer, board[i][j]);
                }
            }
            return;
        }

        int[][] clone = new int[n][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                clone[i][j] = board[i][j];
            }
        }

        //4방향으로 움직이기
        for(int i = 0; i < 4; i++) {
            //해당 방향으로 원본 배열 값 변경하는 메서드
            move(i);
            //다음 게임으로 이동
            solution(L+1);
            //탐색 끝났으면 원본 배열로 되돌리기
            for(int j = 0; j < n; j++) {
                for(int k = 0; k < n; k++) {
                    board[j][k] = clone[j][k];
                }
            }
        }

    }

    private void move(int x) {
        switch (x) {
            //위로 블록 이동
            case 0:
                for(int i = 0; i < n; i++) {
                    int target = 0, flag = 0;
                    for(int j = 0; j < n; j++) {
                        if(board[j][i] != 0) {
                            if(flag == board[j][i]) {
                                board[target - 1][i] = flag * 2;
                                flag = 0;
                                board[j][i] = 0;
                            }
                            else {
                                flag = board[j][i];
                                board[j][i] = 0;
                                board[target][i] = flag;
                                target++;
                            }
                        }
                    }
                }
                break;
            //왼쪽으로 몰기
            case 1:
                for(int i = 0; i < n; i++) {
                    int target = n - 1, flag = 0;
                    for(int j = n - 1; j >= 0; j--) {
                        if(board[j][i] != 0) {
                            if(flag == board[j][i]) {
                                board[target + 1][i] = flag * 2;
                                flag = 0;
                                board[j][i] = 0;
                            }
                            else {
                                flag = board[j][i];
                                board[j][i] = 0;
                                board[target][i] = flag;
                                target--;
                            }
                        }
                    }
                }
                break;
            //왼쪽으로 몰기
            case 2:
                for(int i = 0; i < n; i++) {
                    int target = 0, flag = 0;
                    for(int j = 0; j < n; j++) {
                        if(board[i][j] != 0) {
                            if(flag == board[i][j]) {
                                board[i][target - 1] = flag * 2;
                                flag = 0;
                                board[i][j] = 0;
                            }
                            else {
                                flag = board[i][j];
                                board[i][j] = 0;
                                board[i][target] = flag;
                                target++;
                            }
                        }
                    }
                }
                break;
            //오른쪽으로 몰기
            case 3:
                for(int i = 0; i < n; i++) {
                    int target = n - 1, flag = 0;
                    for(int j = n - 1; j >= 0; j--) {
                        if(board[i][j] != 0) {
                            if(flag == board[i][j]) {
                                board[i][target + 1] = flag * 2;
                                flag = 0;
                                board[i][j] = 0;
                            }
                            else {
                                flag = board[i][j];
                                board[i][j] = 0;
                                board[i][target] = flag;
                                target--;
                            }
                        }
                    }
                }
                break;
            }
        }
    }

'Algorithm > baekjoon' 카테고리의 다른 글

스택 수열  (0) 2022.03.02
Two Dots=========  (0) 2022.03.02
가르침  (0) 2022.03.01
부분수열의 합  (0) 2022.03.01
N-Queen  (0) 2022.02.27