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

문제가 개노가다다 생각 하고 구현하기는 쉬운데 매우 귀찮다 로직은 간단 하다
위로 올릴 경우 내위에 애와 내가 같으면  위에 애를  *  2 하고 그리고 이동 시켰다고 체크 한후 
이동 시킨애는 위로 이동 됬을 거니 굳이 이후 배열에 값을 넣어 주지 않는다.

#include <iostream>
#include <algorithm>
#include <cstring> // For memset
using namespace std;

int n;
int arr[20][20];
int maxBlock = 0;

// 배열 이동 처리 (상하좌우)
void moveArray(int dir, int beforeArr[20][20], int afterArr[20][20]) {
    memset(afterArr, 0, sizeof(int) * 20 * 20); // 결과 배열 초기화
    bool isCombined[20][20] = { false }; // 블록 합쳐진 상태 확인

    if (dir == 0) { // 위로 이동
        for (int j = 0; j < n; j++) {
            int target = 0; // 이동 시킬 애
            for (int i = 0; i < n; i++) {
                if (beforeArr[i][j] == 0) continue;
                if (target > 0 && afterArr[target - 1][j] == beforeArr[i][j] && !isCombined[target - 1][j]) {
                    afterArr[target - 1][j] *= 2;
                    isCombined[target - 1][j] = true;
                }
                else {
                    afterArr[target++][j] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 1) { // 아래로 이동
        for (int j = 0; j < n; j++) {
            int target = n - 1; // 이동 시킬 애
            for (int i = n - 1; i >= 0; i--) {
                if (beforeArr[i][j] == 0) continue;
                if (target < n - 1 && afterArr[target + 1][j] == beforeArr[i][j] && !isCombined[target + 1][j]) {
                    afterArr[target + 1][j] *= 2;
                    isCombined[target + 1][j] = true;
                }
                else {
                    afterArr[target--][j] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 2) { // 왼쪽으로 이동
        for (int i = 0; i < n; i++) {
            int target = 0;// 이동 시킬 애
            for (int j = 0; j < n; j++) {
                if (beforeArr[i][j] == 0) continue;
                if (target > 0 && afterArr[i][target - 1] == beforeArr[i][j] && !isCombined[i][target - 1]) {
                    afterArr[i][target - 1] *= 2;
                    isCombined[i][target - 1] = true;
                }
                else {
                    afterArr[i][target++] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 3) { // 오른쪽으로 이동
        for (int i = 0; i < n; i++) {
            int target = n - 1; // 이동 시킬 애
            for (int j = n - 1; j >= 0; j--) {
                if (beforeArr[i][j] == 0) continue;
                if (target < n - 1 && afterArr[i][target + 1] == beforeArr[i][j] && !isCombined[i][target + 1]) {
                    afterArr[i][target + 1] *= 2;
                    isCombined[i][target + 1] = true;
                }
                else {
                    afterArr[i][target--] = beforeArr[i][j];
                }
            }
        }
    }
}

// 재귀적으로 모든 경우 탐색
void solve(int cnt, int beforeArr[20][20]) {
    if (cnt == 6) {
        // 최댓값 갱신
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                maxBlock = max(maxBlock, beforeArr[i][j]);
            }
        }
        return;
    }

    for (int dir = 0; dir < 4; dir++) { // 네 방향으로 이동
        int afterArr[20][20];
        moveArray(dir, beforeArr, afterArr);
        solve(cnt + 1, afterArr);
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> arr[i][j];
        }
    }

    solve(0, arr);
    cout << maxBlock << endl;
    return 0;
}

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 17135 / C++ / dfs / bfs / 브루트 포스  (0) 2025.01.12
백준 2589 / CPP  (0) 2024.11.29
백준 1038  (0) 2024.11.26
백준 14500  (0) 2024.07.30

+ Recent posts