상세 컨텐츠

본문 제목

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

알고리즘 공부

by Tabris4547 2022. 3. 22. 22:26

본문

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

주사위만 구현한다면

아주 간단하게 풀 수 있는 문제입니다.

다만, 처음 읽을 때

문제를 잘 읽어야하는데요

문제에서 지도 위의 윗면이

1이라고 나오기 때문에

'당연히 1이 맨 위가 아닌가?'

라고 생각하기 쉽습니다.

하지만 문제를 읽어보면

'지도 위의 윗면'이라고 되어있으니

지도랑 가장 가까이 있는 면이 1이다

즉, 맨 아랫면이 1이다라는 게 됩니다.

이제 그려준 다음에

동 서 남 북

각각으로 굴러갈 때에

각 면이 어떻게 바뀌는지만 생각한다면

쉽게 문제를 구할 수 있었습니다.

2022.02.23 - [알고리즘 공부] - [백준 23288번] 주사위 굴리기2(파이썬)

 

[백준 23288번] 주사위 굴리기2(파이썬)

문제를 읽자마자 짜증이 확 밀려오는 길이. 처음에 이게 무슨 소리지? 하고 고민을 많이 하게 되죠. 이 문제는 앞선 로봇청소기 문제를 생각하니 대략적인 문제풀이 방법이 떠오르기는 쉽습니다

door-of-tabris.tistory.com

주사위 굴리기 2를 먼저 푼 기억이 있어서

이 문제는 비교적 쉽게 구했습니다.

 

# 백준 14499 주사위 굴리기
import sys

input = sys.stdin.readline

N, M, x, y, K = map(int, input().split())
graph = []
for i in range(N):
    graph.append(list(map(int, input().split())))
command = list(map(int, input().split()))
# 주사위 초기화
dice = [0, 0, 0, 0, 0, 0, 0]
# 이동케이스 1 동쪽 2 서쪽 3 북쪽 4 남쪽
dx = [0, 0, 0, -1, 1]
dy = [0, 1, -1, 0, 0]
for c in command:
    # 명령을 하나씩 차례대로 설명
    # 현 지점에서 명령대로 이동
    ny = y + dy[c]
    nx = x + dx[c]
    # 범위를 벗어나면 무시하고 넘어간다
    if (nx < 0 or nx >= N) or (ny < 0 or ny >= M):
        continue
    # 동쪽으로 굴림
    if c == 1:
        dice[1], dice[3], dice[4], dice[6] = dice[3], dice[6], dice[1], dice[4]
    # 서쪽으로 굴림
    if c == 2:
        dice[1], dice[4], dice[6], dice[3] = dice[4], dice[6], dice[3], dice[1]
    # 북쪽으로 굴림
    if c == 3:
        dice[1], dice[2], dice[6], dice[5] = dice[2], dice[6], dice[5], dice[1]
    # 남쪽으로 굴림
    if c == 4:
        dice[1], dice[5], dice[6], dice[2] = dice[5], dice[6], dice[2], dice[1]

    # 맨 아래와 현재 칸을 비교하고 수를 넣는다
    if graph[nx][ny] == 0:
        graph[nx][ny] = dice[1]
    else:
        dice[1] = graph[nx][ny]
        graph[nx][ny] = 0

    # 맨 위의 값을 출력
    print(dice[6])
    x = nx
    y = ny

 

물론, 이 문제는 만약 처음에 잘못보고

'1이 윗면이네'

라고 놓고 푸셔도 상관은 없습니다.

실제로 제가 처음에 그렇게 풀었습니다.

 

# 백준 14499 주사위 굴리기

N, M, x, y, K = map(int, input().split())
graph = []
for i in range(N):
    graph.append(list(map(int, input().split())))
command = list(map(int, input().split()))
# 주사위 초기화
dice = [0, 0, 0, 0, 0, 0, 0]
# 이동케이스 1 동쪽 2 서쪽 3 북쪽 4 남쪽
# 이건 x,y만 이동한다는 가정
dx = [0, 0, 0, -1, 1]
dy = [0, 1, -1, 0, 0]

for c in command:
    # 명령을 하나씩 차례대로 설명
    # 현 지점에서 명령대로 이동
    ny = y + dy[c]
    nx = x + dx[c]
    # 범위를 벗어나면 무시하고 넘어간다
    if (nx < 0 or nx >= N) or (ny < 0 or ny >= M):
        continue
    # 동쪽으로 굴림
    if c == 1:
        dice[1], dice[3], dice[6], dice[4] = dice[4], dice[1], dice[3], dice[6]
    # 서쪽으로 굴림
    if c == 2:
        dice[1], dice[4], dice[6], dice[3] = dice[3], dice[1], dice[4], dice[6]
    # 북쪽으로 굴림
    if c == 3:
        dice[1], dice[2], dice[6], dice[5] = dice[5], dice[1], dice[2], dice[6]
    # 남쪽으로 굴림
    if c == 4:
        dice[1], dice[5], dice[6], dice[2] = dice[2], dice[1], dice[5], dice[6]

    # 맨 아래와 현재 칸을 비교하고 수를 넣는다
    if graph[nx][ny] == 0:
        graph[nx][ny] = dice[6]
    else:
        dice[6] = graph[nx][ny]
        graph[nx][ny] = 0

    # 맨 위의 값을 출력
    print(dice[1])
    x = nx
    y = ny

저는 이 문제에서, x y 값 범위를 잘못 설정해서

'맞왜틀'을 반복했습니다.

분명 내 논리가 다 맞는데...

어디서 나간거지...?

해당 문제에서는 

친절하게

x y값에 해당하는 범위를

N과 M으로 줬습니다.

그런데 저는 이 친절을 무시하고

'y값이 리스트의 숫자

x값이 리스트의 최대길이'

graph[y][x]

이렇게 놓고풀자

이렇게 푸는 것이 익숙해지다보니

이 문제를 제출하고

계속 틀렸습니다만 반복해서

화가 많아 났었습니다.

그러다 솔루션보고

범위가 잘못 설정했구나...

하면서 저를 반성했습니다.

컴퓨터는 틀릴 리 없다...

내가 틀린 것이다...

틀린 게 안보인다면

범위부터 차근차근 따져보자.

728x90

관련글 더보기

댓글 영역