Computer_Language/Algorithm

[백준] 14409번 주사위 굴리기 파이썬 해설

Joo-Topia 2019. 10. 1. 00:20

출처 : 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개의 줄에 지도에 쓰여 있는 수가 북쪽부터 남쪽으로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다. 주사위를 놓은 칸에 쓰여 있는 수는 항상 0이다. 지도의 각 칸에 쓰여 있는 수는 10을 넘지 않는 자연수 또는 0이다. 마

www.acmicpc.net

시뮬레이션으로 알고리즘으로 분류된 문제이다.

코딩 테스트를 준비하는 데 있어서 주사위 문제는 필수라고 생각한다.

가장 기본적인 문제부터 견고하게 풀어두면 나중에 유사한 문제가 나왔을 때 반드시 도움이 될 것이다.

 

풀이


주사위 굴리기 문제를 풀기 위해서 먼저 주사위를 굴릴 때 마다 바뀐 주사위 정보를 업데이트해 줄 함수를 구현해야 한다. 아래 코드는 이 문제에 사용된 주사위의 이동 관련 함수이다.

dir_arr = [(0,1),(0,-1),(-1,0),(1,0)]
dice = {1 : 0, 2 : 0, 3 : 0, 4 : 0, 5 : 0, 6 : 0}

def replace_dice(n):
    if n == 1 :
        dice[1], dice[3], dice[4], dice[6] = dice[4], dice[1], dice[6], dice[3]
    elif n == 2:
        dice[1], dice[3], dice[4], dice[6] = dice[3], dice[6], dice[1], dice[4]
    elif n == 3:
        dice[1], dice[2], dice[5], dice[6] = dice[5], dice[1], dice[6], dice[2]
    else:
        dice[1], dice[2], dice[5], dice[6] = dice[2], dice[6], dice[1], dice[5]

 

문제에서 주어지는 명령어는 1 : 동쪽, 2 : 서쪽, 3 : 북쪽, 4 : 남쪽 이기 때문에 주사위에 여섯 면을 다 바꿀 필요가 없다.

 

본격적으로 문제풀이에 접근하기 전에, 문제에서 실수를 유도하게끔 주어진 조건을 짚고 넘어가야한다.

1. 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1)

2. 둘째 줄부터 N개의 줄에 지도에 쓰여 있는 수가 북쪽부터 남쪽으로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다. 

이 문제의 x, y는 일반적인 문제의 x, y와 다르게 주어진다. x가 행이고 y가 열 이다.

우리는 x가 열, y가 행인 문제에 익숙해져 있지만, 잘 기억해야 한다. x : 행 y : 열

 

-정답 코드

import sys
input = sys.stdin.readline

dir_arr = [(0,1),(0,-1),(-1,0),(1,0)]
dice = {1 : 0, 2 : 0, 3 : 0, 4 : 0, 5 : 0, 6 : 0}

def replace_dice(n):
    if n == 1 :
        dice[1], dice[3], dice[4], dice[6] = dice[4], dice[1], dice[6], dice[3]
    elif n == 2:
        dice[1], dice[3], dice[4], dice[6] = dice[3], dice[6], dice[1], dice[4]
    elif n == 3:
        dice[1], dice[2], dice[5], dice[6] = dice[5], dice[1], dice[6], dice[2]
    else:
        dice[1], dice[2], dice[5], dice[6] = dice[2], dice[6], dice[1], dice[5]

if __name__ == "__main__":
    n, m, x, y, k = map(int,input().split())
    arr = []
    for i in range(n):
        arr.append(list(map(int,input().split())))

    for cmd in list(map(int,input().split())):
        t_x = dir_arr[cmd-1][0] + x
        t_y = dir_arr[cmd-1][1] + y

        if (0 <= t_x < n) and (0 <= t_y < m):
            x, y = t_x, t_y
            replace_dice(cmd)
            if arr[x][y] != 0:
                dice[6] = arr[x][y]
                arr[x][y] = 0
            else:
                arr[x][y] = dice[6]
            print(dice[1])

문제에서 주어지는 입력을 모두 저장하고 알고리즘을 문제 풀이 알고리즘이 시작된다.

명령에 따라 움직이게 되는데, 만약 배열 밖을 넘어가게 되는 명령이라면 무시하고 다음 명령으로 넘어가게 된다.

수행할 수 있는 명령이라면, 주사위를 먼저 굴린 후 문제의 조건에 맞게 행동을 한다.

이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다. 0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.

위 규칙을 그대로 구현하면 된다.

 

결과


결과

사실 나는 낚시성 조건에 빠져 6번이나 틀린 문제이다..ㅜ

실제 시험에선 조심하도록 하자.