# 14499 주사위 굴리기
# N*M 지도
# 주사위는 윗면이 1 동쪽방향이 3인 상태로 놓아진다.
def roll(direction,nx,ny):
    global dice,map_list
    if direction == 1:
        dice[0],dice[2],dice[3],dice[5] = dice[3],dice[0],dice[5],dice[2]
    elif direction == 2:
        dice[0],dice[2],dice[3],dice[5] = dice[2],dice[5],dice[0],dice[3]
    elif direction == 3:
        dice[0],dice[1],dice[4],dice[5] = dice[4],dice[0],dice[5],dice[1]
    else:
        dice[0],dice[1],dice[4],dice[5] = dice[1],dice[5],dice[0],dice[4]
    if map_list[nx][ny]:
        dice[5] = map_list[nx][ny]
        map_list[nx][ny] = 0
    else:
        map_list[nx][ny] = dice[5]


N,M,X,Y,K = map(int,input().split())

map_list = [list(map(int,input().split())) for _ in range(N)]

# [1,2,3,4,5,6] 
# 동쪽 1 [4,2,1,6,5,3]
# 서쪽 2 [3,2,6,1,5,4]
# 북쪽 3 [5,1,3,4,6,2]
# 남쪽 4 [2,6,3,4,1,5]
dice = [0]*6
dire = [(0,1),(0,-1),(-1,0),(1,0)]

command_list = list(map(int,input().split()))
for command in command_list:
    nx = X + dire[command-1][0]
    ny = Y + dire[command-1][1]
    if 0<=nx<N and 0<=ny<M:
        roll(command,nx,ny)
    else:
        continue
    X,Y = nx,ny
    print(dice[0])

첫 풀이방식은 문제에 주어진 조건을 그대로 따라 했다.

 

문제에서 보여준 전개도 대로 실행했다. 일단 크기가 6인 리스트를 만들어 주사위로 지정을 했다.

 

문제에서 보여준 전개도에서 각 위치에 해당하는 값은 전개도에 있는 값의 -1에 인덱스에 저장을 했다.

즉 정 가운데는 0번 인덱스, 3번 위치에 있는것은 2번 인덱스에 저장을 했다. 

이런식으로 주사위를 가정하고, 주사위를 동서남북으로 돌렸을때, 인덱스가 바뀌는 위치를 계산해줬다. 그리고 동서남북에 따라, 주사위가 바뀌는 것을 구현해주었다.

 

동서남북명령어가 1,2,3,4로 들어오니 그에 맞춰  이동값을 dire에 저장해줬다. 그 다음에는 명령어를 실행시켜주는 반복문을 하고, 범위를 벗어나는 경우에는 아무것도 출력을 하면 안되니 범위를 벗어나는 경우에는 continue로 넘어가준다. 그렇지 않을 때에는, roll이라는 함수를 실행시켜 주사위를 굴리고, 그 위치에 존재하는 값에 따라 문제에 주여진 조건대로 실행시켰다.

 

하지만 이렇게 풀고난뒤 한가지 불만점이 있었는데, 각 케이스마다 전부 하나하나 인덱스를 바꿔주는 로직이 마음에 들지 않았다.

 

그래서 개선한 코드는 다음과 같다.

 

# 14499 주사위 굴리기
# N*M 지도
# 주사위는 윗면이 1 동쪽방향이 3인 상태로 놓아진다.
def roll(direction,nx,ny):
    global dice,map_list,moving_dice
    dice[0],dice[-1],dice[moving_dice[direction][0]],dice[moving_dice[direction][1]] = dice[moving_dice[direction][0]],dice[moving_dice[direction][1]],dice[-1],dice[0]
    if map_list[nx][ny]:
        dice[5] = map_list[nx][ny]
        map_list[nx][ny] = 0
    else:
        map_list[nx][ny] = dice[5]


N,M,X,Y,K = map(int,input().split())

map_list = [list(map(int,input().split())) for _ in range(N)]

# [1,2,3,4,5,6] 
# 동쪽 1 [4,2,1,6,5,3]
# Top,Bottom,바뀔것1,바뀔것2 = 바뀔것1,바꿀것2,bottm,top
# 서쪽 2 [3,2,6,1,5,4]
# 북쪽 3 [5,1,3,4,6,2]
# 남쪽 4 [2,6,3,4,1,5]
dice = [0]*6
dire = [(0,1),(0,-1),(-1,0),(1,0)]
moving_dice = {1 : [3,2],2:[2,3],3:[4,1],4:[1,4]}
command_list = list(map(int,input().split()))
for command in command_list:
    nx = X + dire[command-1][0]
    ny = Y + dire[command-1][1]
    if 0<=nx<N and 0<=ny<M:
        roll(command,nx,ny)
    else:
        continue
    X,Y = nx,ny
    print(dice[0])

나머지 로직은 전부 동일하지만, 주사위가 굴러갈때의 규칙성이 있다.

 

규칙은 다음과 같다.

 

주사위는 총 6면이 있고, 서로 마주보는걸로 묶을시 3쌍으로 볼수 있다. 주사위를 굴릴 시, 우리가 굴리기전의 Top,bottom 한 쌍과 주사위를 굴러오서 오는 한쌍이 위치가 바뀌고 나머지 한쌍은 그대로 위치한다.

 

           Prev                               -- >>                        Next

굴렸을때 Top에 가는 거                                                 Top

굴렸을때 Bottom에 가는 거                                           Bottom

            Top                                              Prev에서 굴렸을때 Bottom에 가는것이 있었던 위치

         Bottom                                            Prev에서 굴렸을때 Top에 가는 것이 있었던 위치

 

 

글로 설명하기 좀 힘든데 이러한 특징점을 가지고 있따. 그러므로 각 명령어마다, 바뀌는 Index값을 Dictionary에 저장해놓고, 위의 걸 구현해주었다.

 

같은 코드를 여러번 반복하는 것을 막을 수 있었다. 당연히 실전에서는 위의 풀이방식대로 풀 것 같다.

 

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 11403 경로찾기  (0) 2021.01.30
[BOJ/백준] 9251 LCS  (0) 2021.01.29
[BOJ/백준] 9633 N-queen  (0) 2021.01.28
[BOJ/백준] 2174 로봇 시뮬레이션  (0) 2021.01.26
[BOJ/백준] 12851 숨바꼭질 2  (0) 2021.01.25

+ Recent posts