이숭간 공부기록

백준 14499번 파이썬 _ 주사위굴리기 (삼성SW기출) 본문

알고리즘/백준

백준 14499번 파이썬 _ 주사위굴리기 (삼성SW기출)

이숭간 2021. 4. 1. 15:46
728x90

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

  • 문제유형 : 구현, 시뮬레이션
  • 문제풀이
    • 주사위굴리기 구현 - move함수
      • '뱀'문제랑 비슷하게 한가지부분만 좀 어려운걸 구현하면 나머지는 문제요구사항대로 구현하면 된다.
      • '뱀'문제에서의 회전방향의 구현이 그랫듯이 이문제도 주사위를 굴려갈때 각 위치의 숫자를 바꿔주는 것이 중요했다.
      • move()함수로 이동방향이 동서남북중 어디인지를 나타내는 direction을 인자로 받아, 주사위 각 위치의 숫자를 바꿔준다.
      • 주사위에서 각 위치 (맨밑바닥은 인덱스6, 맨위는 인덱스1) 은 변하지 않게하고 매 턴마다 해당 위치에 담기는 숫자만 바꿔주도록한다.
    • 이동후 -> 확인? / 확인후 -> 이동?
      • 이런 그래프(지도)상에서 움직이는 문제의 경우 벽을 넘어가지 않는지 경계값을 확인해야 하는데 
      • 먼저 이동을 한후 이동이 가능한지여부에 따라 행위를 다르게 해주는 문제가있고 (ex) 삼성기출 - 뱀문제)
      • 이동하기전에 이동여부를 먼저 확인한후 이동이 가능할때만 이동을 해주는 문제가 있으므로 주의한다.(이문제)
  • 정답코드
import sys
from collections import deque
input = sys.stdin.readline

#세로,가로 / 주사위좌표 / 명령개수
n,m,x,y,k = map(int, input().split())
board = [[] for _ in range(n)]

#판 입력
for i in range(n):
    input_list = list(map(int, input().split()))
    board[i] = input_list

#동(1) 서(2) 북(3) 남(4) - 우좌상하
order = deque(list(map(int, input().split())))

#우-좌-상-하
dy = [1,-1,0,0]
dx = [0,0,-1,1]
dice = [0,0,0,0,0,0,0]

# 즉 주사위의위치는 고정시키고 값만 계속해서 바꿔주는 함수
def move(direction):
    if direction == 0:
        #동쪽으로 움직0다고 할때, 1번위치에는 이전의 3번위치값이 오게되고 3번위치에는 이전의 6번위치에 오게됨
        dice[1], dice[3], dice[4], dice[6] = dice[3], dice[6], dice[1], dice[4]
    elif direction == 1:
        dice[1], dice[3], dice[4], dice[6] = dice[4], dice[1], dice[6], dice[3]
    elif direction == 2:
        dice[1], dice[2], dice[5], dice[6] = dice[2], dice[6], dice[1], dice[5]
    elif direction == 3:
        dice[1], dice[2], dice[5], dice[6] = dice[5], dice[1], dice[6], dice[2]

#모든 이동을 다 할때까지
while order:
    # 오더에서 하나씩 확인하면서 이동하는데, order넘버에서 -1을 해서 그거토대로 dy,dx인덱스 주면 이동됨
    direction = (order.popleft())-1

    # 초기 - 윗면이 1이고 동쪽을 바라보는 방향이 3
    # 이동한 칸에 쓰여있는 수가 0이면 -> 주사위의 숫자가 칸에 복사됨
    # 이동한 칸에 쓰여잇는 수가 0이 아니면 -> 칸의 숫자가 주사위로 복사됨 -> 칸은 다시 0이됨
    x_temp = x+dx[direction]
    y_temp = y+dy[direction]
    if 0<=x_temp<n and 0<=y_temp<m: #이동가능한경우
        x = x_temp
        y = y_temp
        move(direction)
        #현재바닥 - print(dice[x][y])
        if board[x][y] == 0:
            board[x][y] = dice[6]
        else:
            dice[6] = board[x][y]
            board[x][y] = 0
        print(dice[1])


##실수햇던것 - 이동이 먼저 되는지 확인하고 될때만 이동을 하는것임 ( 어제풀었던 뱀문제는 매번 이동은 무조건 수행한 후에 이동할수없을때는 종료하고 이동할때는 다른행위를
##수행하는것이므로 일단 이동을 먼저 한후에 이동이 가능한지 확인하지만 여기서는 이동확인이 되는지 먼저 확인하고 될때만 이동을 해야함.. *