백준 12100번 2048 (Easy)

Hyun·2023년 9월 7일
0

코딩테스트

목록 보기
40/66
post-thumbnail

https://www.acmicpc.net/problem/12100
실패이유: 구현실패

LIMIT = 5

DOWN = 0
UP = 1
LEFT = 2
RIGHT = 3


def gen(k):                         # 들어온 k값을 4진법 변환을 통해 방향 배열 생성
    a = [0] * LIMIT
    for i in range(LIMIT):
        a[i] = (k & 3)
        k >>= 2
    return a


def check(a, dirs):
    d = [row[:] for row in a]

    for dir in dirs:                                        # 방향 배열의 방향들을 반복 순회
        merged = [[False] * n for _ in range(n)]                # 병합 여부 체크

        while True:                                                 # 더 이상 블록들을 움직일 수 없는 경우까지 반복
            movable = False                                     # 블록들을 더 움직일 수 있는지 여부
            if dir == DOWN:                                   # 아래로 블록들 이동
                for y in range(n - 2, -1, -1):                  # 맨 아래부터 블록 검사 (맨 아래에서 한칸 위부터 시작해서 위로 검사)
                    for x in range(n):
                        if d[y][x] == 0:                        # 현재블록이 0 인 경우
                            continue
                        if d[y + 1][x] == 0:                    # 현재블록이 0이 아니고, 아래가 비어 있는 경우, 현재블록을 아래로 이동
                            d[y + 1][x] = d[y][x]
                            merged[y + 1][x] = merged[y][x]
                            d[y][x] = 0
                            movable = True
                        elif d[y + 1][x] == d[y][x]:                        # 현재블록이 0이 아니고, 바로 아래 블록이 현재블록과 같은 경우
                            if not merged[y][x] and not merged[y + 1][x]:   # 현재블록과 바로 아래블록이 한번도 병합하지 않은 블록인 경우, 병합
                                d[y + 1][x] *= 2
                                merged[y + 1][x] = True
                                d[y][x] = 0
                                movable = True
            elif dir == UP:                                 # 위로 블록들 이동
                for y in range(1, n):
                    for x in range(n):
                        if d[y][x] == 0:
                            continue
                        if d[y - 1][x] == 0:
                            d[y - 1][x] = d[y][x]
                            merged[y - 1][x] = merged[y][x]
                            d[y][x] = 0
                            movable = True
                        elif d[y - 1][x] == d[y][x]:
                            if not merged[y][x] and not merged[y - 1][x]:
                                d[y - 1][x] *= 2
                                merged[y - 1][x] = True
                                d[y][x] = 0
                                movable = True
            elif dir == LEFT:                              # 왼쪽으로 블록들 이동
                for x in range(1, n):
                    for y in range(n):
                        if d[y][x] == 0:
                            continue
                        if d[y][x - 1] == 0:
                            d[y][x - 1] = d[y][x]
                            merged[y][x - 1] = merged[y][x]
                            d[y][x] = 0
                            movable = True
                        elif d[y][x - 1] == d[y][x]:
                            if not merged[y][x] and not merged[y][x - 1]:
                                d[y][x - 1] *= 2
                                merged[y][x - 1] = True
                                d[y][x] = 0
                                movable = True
            elif dir == RIGHT:                          # 오른쪽으로 블록들 이동
                for x in range(n - 2, -1, -1):
                    for y in range(n):
                        if d[y][x] == 0:
                            continue
                        if d[y][x + 1] == 0:
                            d[y][x + 1] = d[y][x]
                            merged[y][x + 1] = merged[y][x]
                            d[y][x] = 0
                            movable = True
                        elif d[y][x + 1] == d[y][x]:
                            if not merged[y][x] and not merged[y][x + 1]:
                                d[y][x + 1] *= 2
                                merged[y][x + 1] = True
                                d[y][x] = 0
                                movable = True
            if not movable:                             # 블록들이 이동할 수 있는 빈칸이나, 병합할 수 있는 블록들이 없는 경우, 반복문 탈출
                break

    max_val = max([max(row) for row in d])              # 블록에서 최대값 반환
    return max_val


n = int(input())
board = [list(map(int, input().split())) for _ in range(n)]

ans = 0
for k in range(4 ** LIMIT):
    dirs = gen(k)
    ans = max(ans, check(board, dirs))

print(ans)
  • gen(k)
    • 0 ~ 4^10 -1 까지의 정수를 4진법을 표현하는 배열로 만들어 방향 배열을 만든다.
  • check(a, dirs)
    • 블록들을 이동한 뒤, 가장 큰 블록을 계산한다.
  • 블록들을 더 이상 움직일 수 없을때까지 블록이동을 반복한다.
    • movable = False

출처: 코드플러스 - 알고리즘 중급 1/3 강의
https://code.plus/course/43

0개의 댓글

관련 채용 정보