알고리즘

백준 12100번 2048 (JAVA)

박카스마시며코딩 2023. 11. 25. 19:24

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

 

12100번: 2048 (Easy)

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

www.acmicpc.net

 

저는 구현을 통해 문제를 해결하였습니다.

dfs로 뎁스가 5인 모든 경우의 수를 찾고 이 중 최대 값을 찾아 문제를 해결하였습니다.

 

package BOJ.simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ_12100_2 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int[][] map = new int[n][n];
        for(int i = 0 ; i < n; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0 ; j < n ; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        int result = cal(0,map,n);
        System.out.println(result);
    }
    private static final int[] DY = {-1,0,1,0};
    private static final int[] DX = {0,1,0,-1};
    private static int cal(int depth, int[][] map , int n){
        if(depth == 5){
//            printArr(map,n);
            return findMaxValue(map,n);
        }
        int result = 0;
        for(int i = 0 ; i < 4 ; i++){
            int[][] next = moveMap(i,map,n);
            result = Math.max(result,cal(depth+1,next,n));
        }
        return result;
    }
    private static final int EMPTY = 0;
    private static int[][] moveMap(int dir, int[][] map, int n) {
        int[][] next = copyMap(map,n);
        boolean[][] used = new boolean[n][n];
        if(dir == 0){ // 위
            for(int i = 0 ; i < n ; i++){
                for(int j = 0 ; j < n ; j++){
                    if(next[i][j] == EMPTY){
                        continue;
                    }
                    int y = i + DY[dir];
                    int x = j + DX[dir];
                    while(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == EMPTY){
                        y += DY[dir];
                        x += DX[dir];
                    }
                    if(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == next[i][j] && !used[y][x]){ // 같은 것 끼리 만났을 때
                        next[y][x] *= 2;
                        next[i][j] = EMPTY;
                        used[y][x] = true;
                        continue;
                    }
                    y -= DY[dir];
                    x -= DX[dir];
                    int value = next[i][j];
                    next[i][j] = EMPTY;
                    next[y][x] = value;
                }
            }
        }
        if(dir == 1){ // 오른쪽
            for(int i = 0 ; i < n ; i++){
                for(int j = n-1; j >= 0 ; j--){
                    if(next[i][j] == EMPTY){
                        continue;
                    }
                    int y = i + DY[dir];
                    int x = j + DX[dir];
                    while(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == EMPTY){
                        y += DY[dir];
                        x += DX[dir];
                    }
                    if(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == next[i][j] && !used[y][x]){ // 같은 것 끼리 만났을 때
                        next[y][x] *= 2;
                        next[i][j] = EMPTY;
                        used[y][x] = true;
                        continue;
                    }
                    y -= DY[dir];
                    x -= DX[dir];
                    int value = next[i][j];
                    next[i][j] = EMPTY;
                    next[y][x] = value;
                }
            }
        }
        if(dir == 2){ // 아래
            for(int i = n-1 ; i >= 0 ; i--){
                for(int j = 0 ; j < n ; j++){
                    if(next[i][j] == EMPTY){
                        continue;
                    }
                    int y = i + DY[dir];
                    int x = j + DX[dir];
                    while(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == EMPTY){
                        y += DY[dir];
                        x += DX[dir];
                    }
                    if(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == next[i][j] && !used[y][x]){ // 같은 것 끼리 만났을 때
                        next[y][x] *= 2;
                        next[i][j] = EMPTY;
                        used[y][x] = true;
                        continue;
                    }
                    y -= DY[dir];
                    x -= DX[dir];
                    int value = next[i][j];
                    next[i][j] = EMPTY;
                    next[y][x] = value;
                }
            }
        }
        if(dir == 3){ // 왼쪽
            for(int i = 0 ; i < n ; i++){
                for(int j = 0 ; j < n ; j++){
                    if(next[i][j] == EMPTY){
                        continue;
                    }
                    int y = i + DY[dir];
                    int x = j + DX[dir];
                    while(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == EMPTY){
                        y += DY[dir];
                        x += DX[dir];
                    }
                    if(y >= 0 && y < n && x >= 0 && x < n && next[y][x] == next[i][j] && !used[y][x]){ // 같은 것 끼리 만났을 때
                        next[y][x] *= 2;
                        next[i][j] = EMPTY;
                        used[y][x] = true;
                        continue;
                    }
                    y -= DY[dir];
                    x -= DX[dir];
                    int value = next[i][j];
                    next[i][j] = EMPTY;
                    next[y][x] = value;
                }
            }
        }
        return next;
    }

    private static int findMaxValue(int[][] map, int n){
        int max = 0;
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < n ; j++){
                max = Math.max(max,map[i][j]);
            }
        }
        return max;
    }
    private static int[][] copyMap(int[][] map,int n){
        int[][] temp = new int[n][n];
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < n ; j++){
                temp[i][j] = map[i][j];
            }
        }
        return temp;
    }
}

'알고리즘' 카테고리의 다른 글

백준 3273번 두 수의 합 (JAVA)  (2) 2023.11.27
백준 1141번 접두사 (JAVA)  (0) 2023.11.26
백준 14503번 로봇 청소기 (JAVA)  (0) 2023.11.24
백준 3190번 뱀 (JAVA)  (0) 2023.11.23
백준 2512번 예산 (JAVA)  (0) 2023.11.22