본문 바로가기
  • Eigenspace of Knowledge
PS

[백준/12100/C] 2048(Easy)

by eigenarea 2025. 6. 28.
반응형

크게 3개의 파트로 나누어서 생각해보아야한다.

1. 좌/우/상/하의 이동을 어떻게 구현할 것인지?

2. 탐색알고리즘을 어떻게 전개할것인가?

3. 최댓값을 판단하는 알고리즘은?

 

2,3은 문제의 태그를 보면 알 수 있다싶이 브루트포스로 해결할 수 있다.

처음에 시간복잡도가 브루트포스를 커버해줄 수 있는지 의문을 가졌지만 GPT님이 계산해주셔서 그냥 그런갑다 납득했다..

 

1.에 대한 해결로는 좌/우로 이동할 때는 temp배열에 변동된 각 행을, 상/하로 이동할 때는 temp배열에 변동된 각 열을 저장해줄 것이다.

 

좌측으로 미는것을 구현해보자면 이러하다 : 

 

board[i][j]가 0이 아닐때 temp에 받을 것인데,

a) 만약에 temp[idx]가 0이면 그냥 입력받고(게임을 생각해보자, 아무것도 없는 부분은 그냥 스킵하고 지나가듯이),

b) temp[idx] == board[i][j]인 상황이라면 2배해주고 idx값을 키운다.

c) 그외의 ( temp[idx] != board[i][j] )인 상황이라면 idx값을 더해주고 입력받는다.

 

이렇게하면 변동된 행을 저장해줄 수 있다.

변동된 행을 원래의 격자배열로 입력시켜주면 해결.

 

우/상/하로 미는것도 같은 방식으로 구현하면 된다.

 

2,3번을 구현하는건 단순하다.

#include <stdio.h>

int N, board[20][20];

void move_left() {
    for (int i = 0; i < N; i++) {
        int temp[20] = {0};
        int idx = 0;
        for (int j = 0; j < N; j++) {
            if (board[i][j] == 0) continue;
            if (temp[idx] == 0) temp[idx] = board[i][j];
            else if (temp[idx] == board[i][j]) temp[idx++] *= 2;
            else temp[++idx] = board[i][j];
        }
        for (int j = 0; j < N; j++) board[i][j] = temp[j];
    }
}

void move_right() {
    for (int i = 0; i < N; i++) {
        int temp[20] = {0};
        int idx = N-1;
        for (int j = N-1; j >=0; j--) {
            if (board[i][j] == 0) continue;
            if (temp[idx] == 0) temp[idx] = board[i][j];
            else if (temp[idx] == board[i][j]) temp[idx--] *= 2;
            else temp[--idx] = board[i][j];
        }
        for (int j = 0; j < N; j++) board[i][j] = temp[j];
    }
}

void move_up() {
    for (int j = 0; j < N; j++) {
        int temp[20] = {0};
        int idx = 0;
        for (int i = 0; i < N; i++) {
            if (board[i][j] == 0) continue;
            if (temp[idx] == 0) temp[idx] = board[i][j];
            else if (temp[idx] == board[i][j]) temp[idx++] *= 2;
            else temp[++idx] = board[i][j];
        }
        for (int i = 0; i < N; i++) board[i][j] = temp[i];
    }
}

void move_down() {
    for (int j = 0; j < N; j++) {
        int temp[20] = {0};
        int idx = N-1;
        for (int i = N-1; i >=0; i--) {
            if (board[i][j] == 0) continue;
            if (temp[idx] == 0) temp[idx] = board[i][j];
            else if (temp[idx] == board[i][j]) temp[idx--] *= 2;
            else temp[--idx] = board[i][j];
        }
        for (int i = 0; i < N; i++) board[i][j] = temp[i];
    }
}

void copy(int src[20][20], int dst[20][20]) {
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            dst[i][j] = src[i][j];
}

int max = 0;

void brute(int T){
    if(!T) {
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                if (board[i][j] > max)
                    max = board[i][j];
        return;
    }
    int backup[20][20];
    for (int d = 0; d < 4; d++) {
        copy(board, backup);
        switch (d) {
            case 0: move_left(); break;
            case 1: move_right(); break;
            case 2: move_up(); break;
            case 3: move_down(); break;
        }
        brute(T - 1);
        copy(backup, board); 
    }

}
int main(){
    scanf("%d", &N);
    for(int i = 0; i<N; i++){
        for(int j = 0; j<N; j++){
            scanf("%d", &board[i][j]);
        }
    }
    brute(5); printf("%d", max);
    return 0;
}

 

 

'PS' 카테고리의 다른 글

[백준/11049/C] 행렬 곱셈 순서  (0) 2025.06.28
[백준/12094/C] 2048(Hard)  (2) 2025.06.28
[백준/1005/C] ACM Craft  (0) 2025.06.27
[백준/2252/C] 줄 세우기  (0) 2025.06.27
[백준/1930/C] 정사면체  (0) 2025.06.23