PS/Python

[백준] 14499 - 주사위 굴리기(파이썬, Python)

w00se 2021. 5. 30. 18:58

https://pixabay.com/ko/photos/우산-햇빛-여자-비-빛-6239364/

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

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도

www.acmicpc.net

해당 문제는 구현문제입니다.

주사위를 굴려서 각 회차마다 주사위의 윗 면에 쓰인 수를 출력하는 게 이 문제의 목적입니다.

 

이 문제의 핵심은 주사위의 상태를 저장하는 방법을 구현하는 것이라 생각합니다.

 

저는 3 X 3 배열에 주사위의 상태를 1 X 6 배열에 각 면에 수를 저장하는 방법을 택했습니다.

 

주사위의 상태를 저장하는 방법은 아래와 같습니다.

- 주사위 상태는 주사위 윗 면과 윗 면을 기준으로 동서남북의 면의 번호를 저장합니다.

(저장하는 건 면에 적힌 수가 아니라 문제에 주어진 각 면의 번호임을 기억해주세요😊)

- 주사위를 동쪽 또는 서쪽으로 굴릴 경우 두 번째 행에만 변화를 줍니다.

- 주사위를 남쪽 또는 북쪽으로 굴릴 경우 두 번째 열에만 변화를 줍니다.

 

초기 상태에서 주사위를 동쪽으로 굴린 경우 주사위 상태는 아래와 같습니다.

 

초기 상태에 동쪽으로 주사위를 굴리면 4번 면이 윗 면이 되고 자연스럽게 3번 면이 바닥으로 갑니다.

또한 초기 상태에서 바닥 면이었던 6번 면이 윗 면을 기준으로 왼쪽 면으로, 초기 상태에서 윗 면이었던 1번 면은 윗 면을 기준으로 오른 쪽 면으로 상태가 바뀝니다.

 

위 방법으로 주사위 상태를 저장하고 문제의 조건을 구현한 코드는 아래와 같습니다.

전체 코드

import sys

def init():
    global diceMap
    diceMap[1][1] = 1
    diceMap[0][1] = 2
    diceMap[1][0] = 4
    diceMap[1][2] = 3
    diceMap[2][1] = 5

def rotateDice(d):
    global diceMap

    if d == 0:
        diceMap[1][2] = diceMap[1][1]
        diceMap[1][1] = diceMap[1][0]
        diceMap[1][0] = 7 - diceMap[1][2]

    elif d == 1:
        diceMap[1][0] = diceMap[1][1]
        diceMap[1][1] = diceMap[1][2]
        diceMap[1][2] = 7 - diceMap[1][0]

    elif d == 2:
        diceMap[0][1] = diceMap[1][1]
        diceMap[1][1] = diceMap[2][1]
        diceMap[2][1] = 7 - diceMap[0][1]

    elif d == 3:
        diceMap[2][1] = diceMap[1][1]
        diceMap[1][1] = diceMap[0][1]
        diceMap[0][1] = 7 - diceMap[2][1]        
        

def moveDice(d):
    global dx, dy, curPos
    cr, cc = curPos

    if not (0 <= cr+dy[d] < N and 0 <= cc+dx[d] < M):
        return False

    rotateDice(d)
    curPos = (cr+dy[d], cc+dx[d])

    return True
    

def copyNumber():
    global numberMap, diceMap, diceNum, curPos
    cr, cc = curPos
    topNum = diceMap[1][1]

    if numberMap[cr][cc] == 0:
        # 주사위 바닥 수 -> 맵의 칸으로 복사
        numberMap[cr][cc] = diceNum[(7 - topNum) - 1]
        
    else:
        # 맵의 칸에 적힌 수 -> 주사위 바닥 수로 복사 및 맵의 칸은 0으로 초기화
        diceNum[(7 - topNum) - 1] = numberMap[cr][cc]
        numberMap[cr][cc] = 0
        
    

if __name__ == "__main__":
    N, M, x, y, k = map(int, sys.stdin.readline().strip().split())

    numberMap = [ list(map(int, sys.stdin.readline().strip().split())) for _ in range(N) ]
    directions = list(map(int, sys.stdin.readline().strip().split()))

    dx = [1, -1, 0, 0]
    dy = [0, 0, -1, 1]

    curPos = (x, y)

    diceMap = [ [0] * 3 for _ in range(3) ]
    diceNum = [0] * 6

    init()

    for d in directions:
        # 이동
        isMovable = moveDice(d-1)

        if isMovable:
            # 수 복사
            copyNumber()
            # 출력
            print(diceNum[diceMap[1][1]-1])