🚩 문제 설명
https://www.acmicpc.net/problem/14499
⏱️ 시간 복잡도
▪명령만큼 돌아야 한다. 명령의 수가 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
'✏️ 𝗔𝗹𝗴𝗼𝗿𝗶𝘁𝗵𝗺 > 백준 알고리즘' 카테고리의 다른 글
[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 |