프로그래밍/알고리즘

[Python] 백준 23288번 - 주사위 굴리기2

고등어찌짐 2022. 9. 21. 20:07

 

1. 현재 x, y 값과 움직여야하는 방향을 구하는 함수를 작성

2. 주사위를 동, 서, 남, 북으로 굴렸을 때의 변화를 미리 함수로 구현 

주사위의 각 행 (?) 은 deque 로 표현하여 주사위 굴림을 간편하게 구현할 수 있음

3. 같은 수를 연속해서 가지는 칸의 갯수를 세어 score 를 계산 

4. k 번 반복하여 총 score 계산

 

from collections import deque
import copy


# 방향에 따라 주사위 굴리기
def move_dice(arr, dir):
    arr = copy.deepcopy(arr)

    if dir == 0:
        arr[1].appendleft(arr[3].pop())
        arr[3] = deque([arr[1].pop()])

    elif dir == 1:
        arr[1].append(arr[3].pop())
        arr[3] = deque([arr[1].popleft()])

    elif dir == 2:
        arr[2].append(arr[1][1])
        arr[3].append(arr[2].popleft())
        arr[0].append(arr[3].popleft())
        arr[1][1] = arr[0].popleft()

    elif dir == 3:
        arr[0].append(arr[1][1])
        arr[3].append(arr[0].popleft())
        arr[2].append(arr[3].popleft())
        arr[1][1] = arr[2].popleft()

    return arr


# 지도에서 연속으로 이동할 수 있는 칸 수 계산
def dfs(arr, x, y, val):
    global max_cnt
    max_cnt += 1
    go_x = [-1, 1, 0, 0]
    go_y = [0, 0, -1, 1]

    for gx, gy in zip(go_x, go_y):
        nx = x + gx
        ny = y + gy

        if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny] and arr[nx][ny] == val:
            visited[nx][ny] = 1
            dfs(arr, nx, ny, val)


# 움직여야하는 방향과 방향에 따른 x, y 좌표값
def set_dir(x, y, dir):
    dx = [0, 0, 1, -1]
    dy = [1, -1, 0, 0]
    nx, ny = x + dx[dir], y + dy[dir]

    if 0 <= nx < n and 0 <= ny < m:
        nx, ny = x + dx[dir], y + dy[dir]
        return nx, ny, dir
    else:
        # 만약, 이동 방향에 칸이 없다면, 이동 방향을 반대로 한 다음 한 칸 굴러간다
        if dir == 0:
            dir = 1
        elif dir == 1:
            dir = 0
        elif dir == 2:
            dir = 3
        elif dir == 3:
            dir = 2
        nx, ny = x + dx[dir], y + dy[dir]
        return nx, ny, dir


if __name__ == '__main__':
    n, m, k = map(int, input().split())
    board = [list(map(int, input().split())) for _ in range(n)]
    dice = [deque([2]), deque([4, 1, 3]), deque([5]), deque([6])]
    dir, ans = 0, 0
    x, y = 0, 0
    clock = {0: 2, 2: 1, 1: 3, 3: 0}
    clock_wise = {0: 3, 3: 1, 1: 2, 2: 0}

    move_dice(dice, 0)
    move_dice(dice, 1)
    move_dice(dice, 2)
    move_dice(dice, 3)

    global max_cnt

    for _ in range(k):
        # 이동 방향으로 한칸 구른다
        x, y, dir = set_dir(x, y, dir)
        dice = move_dice(dice, dir)

        # 점수를 획득한다
        max_cnt = -1
        visited = [[0 for _ in range(m)] for _ in range(n)]
        dfs(board, x, y, board[x][y])
        score = board[x][y] * max_cnt
        if score == 0:
            score = board[x][y]

        ans += score

        # 방향을 바꾼다
        if dice[3][0] > board[x][y]:
            dir = clock.get(dir)
        elif dice[3][0] < board[x][y]:
            dir = clock_wise.get(dir)

    print(ans)