[BJ14499] 주사위 굴리기
✏️ 𝗔𝗹𝗴𝗼𝗿𝗶𝘁𝗵𝗺/백준 알고리즘

[BJ14499] 주사위 굴리기

🚩 문제 설명

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

⏱️ 시간 복잡도
▪명령만큼 돌아야 한다. 명령의 수가 N이라면 O(N)

◾ 맵 위에 주사위를 특정 조건에 맞게 굴리고 주사위의 윗면을 출력하는 문제

◾ 주사위 전개도를 유의해서 풀자.

 

 

 


 

 

 

입출력

n m x y k : (세로, 가로, 주사위좌표, 명령의 개수)

숫자 적힌 지도맵 : n 개의 줄

이동하는 명령들 : k 개의 줄

return 주사위 이동할 때마다 윗면에 쓰인 숫자

✔️ 예제 1

4 2 0 0 8
0 2
3 4
5 6
7 8
4 4 4 1 3 3 3 2
0
0
3
0
0
8
6
3

 

✔️ 예제 2

2 2 0 0 16
0 2
3 4
4 4 4 4 1 1 1 1 3 3 3 3 2 2 2 2
0
0
0
0

 

 


 

 

 

📑 문제 풀이

with 파이썬 (Python)
2시간

import sys

#sys.stdin = open('input.txt', 'rt')
input = sys.stdin.readline
n, m, x, y, k = map(int, input().split())
mp = [list(map(int, input().split())) for _ in range(n)]  # 지도의 좌표
com = list(map(int, input().split()))  # 명령의 수
dice = [0] * 6

# 동서북남
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]


# 방향 바꾸기
def roll(d):
    tmp = dice[0]
    # 동
    if d == 1:
        dice[0] = dice[3]
        dice[3] = dice[5]
        dice[5] = dice[2]
        dice[2] = tmp
    # 서
    elif d == 2:
        dice[0] = dice[2]
        dice[2] = dice[5]
        dice[5] = dice[3]
        dice[3] = tmp
    # 북
    elif d == 3:
        dice[0] = dice[4]
        dice[4] = dice[5]
        dice[5] = dice[1]
        dice[1] = tmp
    # 남
    else:
        dice[0] = dice[1]
        dice[1] = dice[5]
        dice[5] = dice[4]
        dice[4] = tmp
        return


def move(d):
    global x, y

    # 만약, 해당 칸의 수가 0 이라면
    if mp[x][y] == 0:
        mp[x][y] = dice[5]  # 주사위의 바닥칸이 복사
    else:
        dice[5] = mp[x][y]  # 칸에 쓰여진 수가 주사위에 복사
        mp[x][y] = 0  # 칸에 쓰여진 수는 0이 된다.

    print(dice[0])


if __name__ == '__main__':
    ans = 0

    for d in com:
        # 방향에 맞게 이동
        x += dx[d - 1]
        y += dy[d - 1]

        # 바깥이동 시
        if any([x < 0, x > n - 1, y < 0, y > m - 1]):
            x -= dx[d - 1]
            y -= dy[d - 1]
            continue

        roll(d)  # 주사위를 굴린다
        move(d)  # 주사위를 이동시킨다

💬 Point

➡️  주사위 전개도를 그려보자
➡️  동서북남 방향 주의

◾ 주사위를 굴릴 때 전개도가 어떻게 변화하는지를 잘 파악하면 쉽게 풀 수 있는 문제

◾ 방향 변환에 따른 주사위 전개도 상황

앞면을 기준으로 해당 전개도 모양으로 펼친다고 생각을 해야한다.

저렇게 펼치게 되면 해당 모양대로의 수열을 얻을 수 있다. 따라서 방향에 따라 요소의 인덱스가 어떻게 변화하는지 알 수 있게 된다.

원래 주사위를 가지고 동쪽으로 돌리면 첫번째 요소는 세번째에 있게 되고 이러한 형식이다.

# 방향 바꾸기
def roll(d):
    tmp = dice[0]
    # 동
    if d == 1:
        dice[0] = dice[3]
        dice[3] = dice[5]
        dice[5] = dice[2]
        dice[2] = tmp
    # 서
    elif d == 2:
        dice[0] = dice[2]
        dice[2] = dice[5]
        dice[5] = dice[3]
        dice[3] = tmp
    # 북
    elif d == 3:
        dice[0] = dice[4]
        dice[4] = dice[5]
        dice[5] = dice[1]
        dice[1] = tmp
    # 남
    else:
        dice[0] = dice[1]
        dice[1] = dice[5]
        dice[5] = dice[4]
        dice[4] = tmp
        return

따라서 다음과 같은 함수를 만들 수 있다. 주사위를 굴리면 요소를 변경하는 함수이다.

 

def move(d):
    global x, y

    # 만약, 해당 칸의 수가 0 이라면
    if mp[x][y] == 0:
        mp[x][y] = dice[5]  # 주사위의 바닥칸이 복사
    else:
        dice[5] = mp[x][y]  # 칸에 쓰여진 수가 주사위에 복사
        mp[x][y] = 0  # 칸에 쓰여진 수는 0이 된다.

    print(dice[0])

◾ 주사위를 지도에서 옮길 때 필요한 함수이다.

만약 해당 칸의 수가 0이라면 칸에 주사위의 바닥칸이 복사된다.

그렇지 않다면, 주사위 숫자가 칸에 복사된다. 그리고 칸에 쓰여진 수는 0으로 처리를 해야한다.

여기서 global 키워드를 이용하여 x, y 좌표 위치를 전역변수로 사용하는 것이 중요하다.

 

if __name__ == '__main__':
    ans = 0

    for d in com:
        # 방향에 맞게 이동
        x += dx[d - 1]
        y += dy[d - 1]

        # 바깥이동 시
        if any([x < 0, x > n - 1, y < 0, y > m - 1]):
            x -= dx[d - 1]
            y -= dy[d - 1]
            continue

        roll(d)  # 주사위를 굴린다
        move(d)  # 주사위를 이동시킨다

◾ 명령에 따라 방향에 맞게 다음 이동 위치를 그려본다.

만약 바깥으로 이동시에는 continue 를 하여 수행과 출력이 되지 않도록 한다.

그 외의 경우에는 주사위를 굴리고 이동시켜서 앞면을 출력한다.

 

 

 

 

 

 

 

 

 

 

 

# 알고리즘 백준 주사위 굴리기 파이썬 BJ14499

# 알고리즘 백준 주사위 굴리기 python bj14499


 

728x90

'✏️ 𝗔𝗹𝗴𝗼𝗿𝗶𝘁𝗵𝗺 > 백준 알고리즘' 카테고리의 다른 글

[BJ14501] 퇴사  (0) 2022.04.30
[BJ14500] 테트로미노  (0) 2022.04.30
[BJ13458] 시험 감독  (0) 2022.04.28
[BJ3190] 뱀  (0) 2022.04.28
[BJ12100] 2048 (Easy)  (0) 2022.04.28