[백준 14499] 주사위 굴리기

코뉴·2022년 2월 8일
0

백준🍳

목록 보기
100/149
post-custom-banner

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

🥚문제


🥚입력/출력


🍳코드

import sys
input = sys.stdin.readline

N, M, x, y, K = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
cmd_list = list(map(int, input().split()))


def roll_dice(dice, dx, dy):
    new_dice = [[-1]*3 for _ in range(4)]
    # 남, 북으로 굴릴 때
    if dy == 0:
        # col = 1인 값들 수정
        # 남쪽으로 굴리는 경우
        if dx == 1:
            new_dice[0][1] = dice[-1][1]
            new_dice[1][1] = dice[0][1]
            new_dice[2][1] = dice[1][1]
            new_dice[3][1] = dice[2][1]
        # 북쪽으로 굴리는 경우
        else:
            new_dice[0][1] = dice[1][1]
            new_dice[1][1] = dice[2][1]
            new_dice[2][1] = dice[3][1]
            new_dice[3][1] = dice[0][1]
        # 좌, 우 유지
        new_dice[1][0] = dice[1][0]
        new_dice[1][2] = dice[1][2]
    # 동, 서로 굴릴 때
    else:
        # 서쪽으로 굴리는 경우
        if dy == -1:
            new_dice[1][0] = dice[1][1]
            new_dice[1][1] = dice[1][2]
            new_dice[1][2] = dice[3][1]
            new_dice[3][1] = dice[1][0]
        # 동쪽으로 굴리는 경우
        else:
            new_dice[1][0] = dice[3][1]
            new_dice[1][1] = dice[1][0]
            new_dice[1][2] = dice[1][1]
            new_dice[3][1] = dice[1][2]
        # 동, 서로 굴려도 유지되는 부분
        new_dice[0][1] = dice[0][1]
        new_dice[2][1] = dice[2][1]
    return new_dice


# 주사위의 전개도
# (1, 1)이 항상 상단의 숫자라고 본다
dice = [[-1]*3 for _ in range(4)]
dice[0][1] = dice[1][0] = dice[1][1] = dice[1][2] = dice[2][1] = dice[3][1] = 0

# 이동 방향
dirs = {1: (0, 1), 2: (0, -1), 3: (-1, 0), 4: (1, 0)}

for cmd in cmd_list:

    dx = dirs[cmd][0]
    dy = dirs[cmd][1]

    # 이동한 칸의 좌표
    nx = x + dx
    ny = y + dy

    if 0 <= nx < N and 0 <= ny < M:
        # 주사위를 굴림
        dice = roll_dice(dice, dx, dy)

        # 이동 칸에 쓰여있는 수가 0
        if arr[nx][ny] == 0:
            # 주사위의 바닥면에 쓰여있는 수가 칸에 복사
            arr[nx][ny] = dice[3][1]
        # 0이 아닌 경우
        else:
            # 칸에 쓰여있는 수가 주사위 바닥으로 복사
            dice[3][1] = arr[nx][ny]
            arr[nx][ny] = 0

        # x, y update
        x = nx
        y = ny

        # 주사위가 이동했을 때마다 상단에 쓰여 있는 값
        print(dice[1][1])

🧂아이디어

구현

  • 주사위의 어떤 면에 어떤 숫자가 써있는지를 어떻게 나타낼지 고민하다가 문제에서 주어진 전개도를 이용하기로 했다.
  • 주사위의 전개도를 나타내는 2차원 리스트 dice를 이용하여 주사위를 굴린 뒤의 정보를 업데이트해준다.
  • 항상 dice[1][1]이 윗면, dice[3][1]이 주사위의 바닥면이 되도록 한다.
  • roll_dice는 주사위를 dx, dy 방향으로 굴린 후의 새로운 전개도인 new_dice를 리턴하는 함수인데,
  • 위 첨부해둔 스케치에서도 알 수 있듯, 굴리는 방향에 따라 전개도를 업데이트 해주면 된다.

  • 사실 굳이 전개도를 나타내기 위해 2차원 리스트를 쓸 필요는 없고, 1차원 리스트로 한 뒤 각각의 인덱스마다 어떤 면인지 의미를 부여해줘도 된다.

  • e.g., dice = [0, 0, 0, 0, 0, 0]이고, dice[0]은 항상 윗면, ...(그 외 다른 인덱스에 대해서도 의미 부여) ... dice[5]는 항상 바닥면으로 유지

profile
코뉴의 도딩기록
post-custom-banner

0개의 댓글