본문 바로가기

Algorithm & Data Structure

백준 - 14499번(큐, 구현, 주사위)

728x90
반응형

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

 

import sys
from collections import deque

n, m, x, y, k = map(int, sys.stdin.readline().split())

ver_dice = deque([0, 0, 0, 0]) #세로로 이동시 각 주사위면의 값 ver_dice[0] = 지도랑 맞닿는 면
par_dice = deque([0, 0, 0, 0]) #가로로 이동시 각 주사위면의 값 par_dice[0] = 지도랑 맞닿는 면

maap = [] #지도
for _ in range(n):
    maap.append(list(map(int, sys.stdin.readline().split())))

command = deque(map(int, sys.stdin.readline().split())) #명령들 담아두기 

before = 0 #이전에 수행했던 명령

while command:
    now = command.popleft() #현재 받은 명령

    if now == 1:
        if y + 1 < m:
            # 만약 이전에 좌우로 이동하는 명령을 수행했다면 상하로 이동할때는 
            # 현재 지도에 맞닿았던 면과 그 면을 마주 보는 면만 유지된다. 
            if before == 3 or before == 4:
                par_dice[0] = ver_dice[0]
                par_dice[2] = ver_dice[2]

            par_dice.append(par_dice.popleft())
            y = y + 1

            if maap[x][y] == 0:
                maap[x][y] = par_dice[0]
            else:
                par_dice[0] = maap[x][y]
                maap[x][y] = 0
            before = now

            print(par_dice[2])

    elif now == 2:
        if y - 1 >= 0:
            if before == 3 or before == 4:
                par_dice[0] = ver_dice[0]
                par_dice[2] = ver_dice[2]

            par_dice.appendleft(par_dice.pop())
            y = y - 1

            if maap[x][y] == 0:
                maap[x][y] = par_dice[0]
            else:
                par_dice[0] = maap[x][y]
                maap[x][y] = 0
            before = now

            print(par_dice[2])

    elif now == 3:
        if x - 1 >= 0:
            if before == 1 or before == 2:
                ver_dice[0] = par_dice[0]
                ver_dice[2] = par_dice[2]

            ver_dice.appendleft(ver_dice.pop())
            x = x - 1

            if maap[x][y] == 0:
                maap[x][y] = ver_dice[0]
            else:
                ver_dice[0] = maap[x][y]
                maap[x][y] = 0
            before = now

            print(ver_dice[2])

    elif now == 4:
        if x + 1 < n:
            if before == 1 or before == 2:
                ver_dice[0] = par_dice[0]
                ver_dice[2] = par_dice[2]

            ver_dice.append(ver_dice.popleft())
            x = x + 1

            if maap[x][y] == 0:
                maap[x][y] = ver_dice[0]
            else:
                ver_dice[0] = maap[x][y]
                maap[x][y] = 0
            before = now

            print(ver_dice[2])

재미있는 구현 문제다.

아이디어를 떠올리는 것이 중요하다. 원소 6개짜리 큐를 만들어서 풀 생각을 하면 안 된다.

주사위를 잘 생각해보자. 주사위를 상하좌우로 굴리는 문제다.

우선 상하로 굴릴 때만 생각해보면 큐를 이용해서 맨 앞을 빼고 맨 뒤에 넣거나 맨뒤를 빼서 맨 앞에 넣으면 자연스럽게 회전하는 주사위를 만들 수 있다. 상하로 굴릴 때는 4개의 면만 쓰기 때문에 큐에 필요한 원소의 개수는 4개이다.

상하로 굴리다가 좌우로 굴리는 명령이 들어오면 기존에 맞닿아 있던 면과 해당 면을 마주 보는 면을 제외하고는 나머지 2개의 면은 상하에 굴리던 면과 값이 다르게 된다. 따라서 이전 명령을 기억하고 있다가 상하 -> 좌우 or 좌우 -> 상하로 이동이 바뀌는 경우 가장 밑에 맞닿는 면과 마주 보는 면의 값(여기서는 par_dice [0], par_dice [2] or ver_dice [0], ver_dice [2])의 값을 이전 명령의 값으로 바꿔줘서 실행하면 답을 구할 수 있다. 아이디어 떠올리는 게 쉽지 않았지만 재미있게 풀었다.

728x90
반응형