[λ°±μ€€] 12100 2048 (easy)

eunbiΒ·2022λ…„ 8μ›” 12일
0
post-thumbnail

πŸ” 12100 2048 (easy)

2048 κ²Œμž„μ€ 4Γ—4 크기의 λ³΄λ“œμ—μ„œ 혼자 μ¦κΈ°λŠ” μž¬λ―ΈμžˆλŠ” κ²Œμž„μ΄λ‹€. 이 링크λ₯Ό λˆ„λ₯΄λ©΄ κ²Œμž„μ„ ν•΄λ³Ό 수 μžˆλ‹€.

이 κ²Œμž„μ—μ„œ ν•œ 번의 이동은 λ³΄λ“œ μœ„μ— μžˆλŠ” 전체 블둝을 μƒν•˜μ’Œμš° λ„€ λ°©ν–₯ 쀑 ν•˜λ‚˜λ‘œ μ΄λ™μ‹œν‚€λŠ” 것이닀. μ΄λ•Œ, 같은 값을 κ°–λŠ” 두 블둝이 μΆ©λŒν•˜λ©΄ 두 블둝은 ν•˜λ‚˜λ‘œ ν•©μ³μ§€κ²Œ λœλ‹€. ν•œ 번의 μ΄λ™μ—μ„œ 이미 합쳐진 블둝은 또 λ‹€λ₯Έ 블둝과 λ‹€μ‹œ ν•©μ³μ§ˆ 수 μ—†λ‹€. (μ‹€μ œ κ²Œμž„μ—μ„œλŠ” 이동을 ν•œ 번 ν•  λ•Œλ§ˆλ‹€ 블둝이 μΆ”κ°€λ˜μ§€λ§Œ, 이 λ¬Έμ œμ—μ„œ 블둝이 μΆ”κ°€λ˜λŠ” κ²½μš°λŠ” μ—†λ‹€) λ˜‘κ°™μ€ μˆ˜κ°€ μ„Έ κ°œκ°€ μžˆλŠ” κ²½μš°μ—λŠ” μ΄λ™ν•˜λ €κ³  ν•˜λŠ” μͺ½μ˜ 칸이 λ¨Όμ € 합쳐진닀. 예λ₯Ό λ“€μ–΄, μœ„λ‘œ μ΄λ™μ‹œν‚€λŠ” κ²½μš°μ—λŠ” μœ„μͺ½μ— μžˆλŠ” 블둝이 λ¨Όμ € ν•©μ³μ§€κ²Œ λœλ‹€. 이 λ¬Έμ œμ—μ„œ λ‹€λ£¨λŠ” 2048 κ²Œμž„μ€ λ³΄λ“œμ˜ 크기가 NΓ—N 이닀. λ³΄λ“œμ˜ 크기와 λ³΄λ“œνŒμ˜ 블둝 μƒνƒœκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, μ΅œλŒ€ 5번 μ΄λ™ν•΄μ„œ λ§Œλ“€ 수 μžˆλŠ” κ°€μž₯ 큰 λΈ”λ‘μ˜ 값을 κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.


πŸ€” 풀이

  • (λ‹€ ν‘ΈλŠ”λ° 2μ‹œκ°„ λ„˜κ²Œ κ±Έλ¦°λ“― ν’€λ©΄μ„œ 눈물이 λ‚¬λ»”ν–ˆλ‹€... μ›λž˜ ν’€λ˜ 방식이 μ•ˆ λΌμ„œ κ²°κ΅­ μ‹Ή λ‹€ μ—Žκ³  λ…ΈνŠΈμ— 적어가며 μ°¨κ·Όμ°¨κ·Ό λ‹€μ‹œ 섀계...)

  • μš°μ„  λͺ‡ 번 이동 이런거 없이 ν•œ 번 이동할 λ•Œ μ œλŒ€λ‘œ λ˜λŠ”μ§€λΆ€ν„° 확인해야 ν–ˆλ‹€. λ‚΄κ°€ μƒκ°ν•œ 방법은
    1. λ°©ν–₯λŒ€λ‘œ μ‹Ή λ°€μ–΄μ„œ ν•œ ꡰ데둜 λͺ¨μ€λ‹€. (μˆœμ„œλ₯Ό 지킀며)
    2. λ°€μ–΄μ„œ λͺ¨μ€ μˆ«μžλ“€μ„ 확인해 ν•©μ³μ§€λŠ” 쑰건에 λ§žλŠ” μˆ«μžλ“€μ„ μ²˜λ¦¬ν•œλ‹€.
    3. μœ„μ—μ„œ μ²˜λ¦¬ν•œ μˆ«μžλ“€μ„ λ‹€μ‹œ λ³΄λ“œμ— μ±„μš΄λ‹€.
    이닀. ν•΄λ‹Ή λ°©λ²•λŒ€λ‘œ μ–΄λ–»κ²Œ κ΅¬ν˜„ν• μ§€ λ°‘μ—μ„œ λ‹€μ‹œ μ„€λͺ…ν•΄λ³Έλ‹€.

  1. λ°©ν–₯λŒ€λ‘œ μ‹Ή λ°€κΈ°.
    • 말 κ·ΈλŒ€λ‘œ λƒ…λ‹€ λ°€μ–΄μ„œ save에 λ„£λŠ”λ‹€. λ‹€λ§Œ, 0이 μ±„μ›Œμ Έ μžˆμ„ κ²½μš°μ—λŠ” ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
  2. 숫자 ν•©μΉ˜κΈ°
    • 쑰건을 ν™•μΈν•˜μ—¬ 숫자λ₯Ό ν•©μΉœλ‹€. μ—¬κΈ°μ„œ ν•œ 번 합쳐진 μˆ«μžλŠ” λ‹€μ‹œ λ‹€λ₯Έ μˆ«μžμ™€ 합쳐지지 μ•ŠμœΌλ―€λ‘œ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. λ‚˜λŠ” 마치 μŠ€νƒ ꡬ쑰처럼 κΊΌλ‚΄ ν•©μΉ  수 μžˆλŠ”μ§€ ν™•μΈν–ˆλ‹€. saveμ—μ„œ 숫자λ₯Ό ν•˜λ‚˜μ”© κΊΌλ‚Έλ‹€. 이 숫자λ₯Ό κΊΌλ‚Ό λ•Œ, pre_numκ³Ό λΉ„κ΅ν•œλ‹€.(λ‹€λ§Œ pre_num은 이전에 ν•œ 번 합쳐진 μˆ«μžκ°€ 듀어가지 μ•Šκ²Œ ν•œλ‹€.) μ΄λŠ” λ°”λ‘œ μ•žμ— 있던 숫자둜, λ§Œμ•½ (방금 κΊΌλ‚Έ)λ‚˜μ™€ 값이 λ˜‘κ°™μ§€ μ•Šλ‹€λ©΄, λ¬΄μ‹œν•˜κ³  κ·Έλƒ₯ μƒˆλ‘œμš΄ list에 κΊΌλ‚Έ 값을 λ„£λŠ”λ‹€. 그리고 pre_num은 방금 넣은 값이 λœλ‹€. ν•˜μ§€λ§Œ λ§Œμ•½ λ˜‘κ°™λ‹€λ©΄ 두 μˆ«μžλŠ” 합쳐져 μƒˆλ‘œμš΄ list에 λ“€μ–΄κ°€κ²Œ λœλ‹€. 그리고 pre_num을 -1둜 λ§Œλ“€μ–΄ μ£Όμ–΄μ•Ό ν•œλ‹€. 그렇지 μ•ŠμœΌλ©΄ 이후 λ˜‘κ°™μ€ μˆ«μžμ™€ ν•©μ³μ§€κ²Œ λ˜λŠ” 꼴이 될 수 있기 λ•Œλ¬Έμ΄λ‹€. 이λ₯Ό save의 λͺ¨λ“  값을 확인할 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.
  3. λ§ˆμ§€λ§‰μœΌλ‘œ ν•©μΉœ μˆ«μžλ“€μ„ λ‹€μ‹œ λ³΄λ“œμ— μ λŠ”λ‹€.
    - 밀어진 λ°©ν–₯을 μ‹œμž‘μœΌλ‘œ λ‹€μ‹œ μˆ«μžλ“€μ„ μ±„μš΄λ‹€. λ§Œμ•½ μ±„μšΈ μˆ«μžκ°€ μ—†μœΌλ©΄ 0으둜 μ±„μš΄λ‹€.

    (λ‚˜λŠ” λ°©ν–₯ μˆœμ„œλŒ€λ‘œ μ±„μš΄λ‹€κ³  4가지 μΌ€μ΄μŠ€λ‘œ λ‚˜λˆ„μ—ˆλŠ”λ° νšŒμ „μ„ μ‚¬μš©ν•˜μ‹  뢄도 계셨닀... λ‚˜λŠ” μ–Έμ œμ―€ 그런 μ„ΌμŠ€λ₯Ό κ°–κ²Œ 될까...)
  • 각각 이동이 잘 λ˜λŠ”κ±Έ ν™•μΈν–ˆμœΌλ―€λ‘œ, 5번 이동할 수 μžˆλŠ” 경우의 수λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ ν•΄λ‹Ή 과정을 λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ μ§„ν–‰ν•œλ‹€. (μ—¬κΈ°μ„œ λ°”λ€ŒλŠ” λ³΄λ“œλ₯Ό μ²΄ν¬ν•˜κΈ° μœ„ν•΄ copy ν•¨μˆ˜λ₯Ό μΌλŠ”λ°, temp_boardλ₯Ό λ°–μœΌλ‘œ λΉΌλ‚΄μ„œ κ±°κΈ°μ„œ 계산해도 됐을 것 κ°™λ‹€.)

πŸ“ μ½”λ“œ

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, maxx = 0;
int board[20][20];

vector<int> save[20];
vector<int> list[20];
int dx[2] = { 0, 1 }; // μœ„, μ™Ό, μ•„λž˜, 였
int dy[2] = { 1, 0 };


void initialVector() {
    for (int i = 0; i < N; i++) {
        save[i].clear();
        list[i].clear();
    }
}

void reposition(int direction) {    // 3.
    int x, y;

    if (direction == 0) {
        for (int i = 0; i < N; i++) { // dir 0
            for (int j = 0; j < N; j++) {
                if (list[j].size() > i) {
                    board[i][j] = list[j][i];
                    if (maxx < board[i][j]) maxx = board[i][j];
                }
                else {
                    board[i][j] = 0;
                }
            }
        }
    }
    else if (direction == 1) {
        for (int i = 0; i < N; i++) { // dir 1
            for (int j = 0; j < N; j++) {
                if (list[i].size() > j) {
                    board[i][j] = list[i][j];
                    if (maxx < board[i][j]) maxx = board[i][j];
                }
                else {
                    board[i][j] = 0;
                }
            }
        }
    }
    else if (direction == 2) {
        for (int i = N-1; i >= 0; i--) { // dir 2
            for (int j = N-1; j >= 0; j--) {
                if (list[j].size() > (N-i-1)) {
                    board[i][j] = list[j][N-i-1];
                    if (maxx < board[i][j]) maxx = board[i][j];
                }
                else {
                    board[i][j] = 0;
                }
            }
        }
    }
    else if (direction == 3) {
        for (int i = N-1; i >= 0; i--) { // dir 3
            for (int j = N-1; j >= 0; j--) {
                if (list[i].size() > (N-j-1)) {
                    board[i][j] = list[i][N-j-1];
                    if (maxx < board[i][j]) maxx = board[i][j];
                }
                else {
                    board[i][j] = 0;
                }
            }
        }
    }

}

void merge() {  // 2.
    for (int i = 0; i < N; i++) {
        int pre_num = -1;
        int top_idx = 0;
        while (top_idx < save[i].size()) {
            if (save[i][top_idx] == pre_num) {
                pre_num = -1;
                list[i].pop_back();
                list[i].push_back(save[i][top_idx++]*2);
            }
            else {
                pre_num = save[i][top_idx++];
                list[i].push_back(pre_num);
            }
        }
    }
}

void push(int direction) { // 1.
    int x, y;
    if (direction/2 == 0) {
        for (int x = 0; x < N; x++) {
            for (int y = 0; y < N; y++) {
                if (board[x][y] != 0) save[x*dx[direction%2] + y*dy[direction%2]].push_back(board[x][y]);
            }
        }
    }
    else {
        for (int x = N-1; x >= 0; x--) {
            for (int y = N-1; y >= 0; y--) {
                if (board[x][y] != 0) save[x*dx[direction%2] + y*dy[direction%2]].push_back(board[x][y]);
            }
        }
    }
}

void find_max() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (maxx < board[i][j]) maxx = board[i][j];
        }
    }
}

void bt(int step) {
    if (step == 5) {
        return ;
    }

    int temp_board[20][20];
    copy(&board[0][0], &board[0][0]+400, &temp_board[0][0]);
    for (int i = 0; i < 4; i++) {
        initialVector();
        copy(&temp_board[0][0], &temp_board[0][0]+400, &board[0][0]);
        push(i);
        merge();
        reposition(i);
        bt(step+1);
    }
}

int main() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> board[i][j];
        }
    }
    bt(0);

    cout << maxx;
    return 0;
}

0개의 λŒ“κΈ€