



이 문제는 삼성sw 역량 테스트 기출 문제에 속하는데요. 삼성 코테 유형은 대체로 구현이 많이 나옵니다. 차근차근 문제를 이해하고 종이에 써가면서 풀어본다면, 끈기와 빨리 풀 수 있는 실력만 있다면 충분히 푸실 수 있는 문제입니다.
겉으로 봤을 땐, DFS나 BFS로 푸는 문제인 것 같지만, 단순 구현으로도 풀리는 문제입니다.
먼저 문제를 이해해보록할게요.
보드가 있구요. 보드 위에 주사위가 있습니다. 주사위는 보드 위 숫자가 0인 부분에 있고 명령에 따라서 굴리는 문제라고 보시면 됩니다.
그럼, 아래 문제의 내용이 이해가시나요?

주사위가 보드 위에서 굴려질 때마다 주사위 면에 적혀지는 숫자와 보드위에 적혀지는 숫자가 달라진다는 것을 알 수 있습니다. 즉, 주사위가 굴려짐에 따라 보드와 주사위의 숫자가 달라진다는 것이죠.
그렇다면, 주사위가 어느 방향으로 굴려질 때, 어떤 면이 어디로 오는지, 즉 주사위의 전개도에 따른 변화를 알아볼 필요가 있겠는데요, 복잡하지 않습니다.
구현의 특징은 그려보면 웬만해서는 다 해결이 돼요. 하지만, 모두가 미리 겁먹고 혹은 조금 더 효율적인 풀이가 있지는 않을까 하고 그러한 시도를 주저하게 되더라구요. 그러면 또, 시간은 가고 초조해지니까 그제서야 종이에 적어보면서 풀어보는데, 이미 시간은 흘렀겠죠..! 그러니까, 바로 종이에 그려보는 것을 주저하지 맙시다...!

각 명령은 (상,하,좌,우) 로 4가지 경우만 존재하므로, 각 명령에 따라 주사위 면의 숫자가 어디로 바뀌는지 갱신하면 됩니다.
나머지 풀이는 코드를 토대로 설명드리겠습니다.
import sys
input = sys.stdin.readline
n, m, x, y, k = map(int,input().split())
# print(n,m,x,y,k)
board = []
for i in range(n):
row = list(map(int,input().split()))
board.append(row)
# print(graph)
cmd = list(map(int,input().split()))
# print(cmd)
dr = [0,0,-1,1] # 우 좌 상 하 (행)
dc = [1,-1,0,0] # 우 좌 상 하 (열)
dice = [0,0,0,0,0,0] # 위 뒤 오른쪽 왼쪽 앞 아래
def go(cmd):
a, b, c, d, e, f = dice[0],dice[1],dice[2],dice[3],dice[4],dice[5]
if cmd == 1 : # 동
dice[0],dice[1],dice[2],dice[3],dice[4],dice[5] = d,b,a,f,e,c
elif cmd == 2: # 서
dice[0],dice[1],dice[2],dice[3],dice[4],dice[5] = c,b,f,a,e,d
elif cmd == 3: # 북
dice[0],dice[1],dice[2],dice[3],dice[4],dice[5] = e,a,c,d,f,b
elif cmd == 4: # 남
dice[0],dice[1],dice[2],dice[3],dice[4],dice[5] = b,f,c,d,a,e
nr, nc = x,y # 시작 좌표
for i in cmd:
# print(i)
nr += dr[i-1]
nc += dc[i-1]
if nr < 0 or nr >= n or 0 > nc or nc >= m:
nr -= dr[i-1]
nc -= dc[i-1]
continue
go(i)
if board[nr][nc] == 0:
board[nr][nc] = dice[-1]
else:
dice[-1] = board[nr][nc]
board[nr][nc] = 0
print(dice[0])
문제에서 (동,서,북,남) 순으로 커맨드가 (1,2,3,4)이므로
(동,서,북,남) 순으로 행렬 이동 리스트 dr,dc를 만들어줍니다.
그러면 명령리스트 cmd를 돌 때, (각 명령 숫자-1)이 그 리스트의 방향이동 좌표가 됩니다.
예를 들어, 명령 커맨드가 "4"라면 남쪽으로 이동하라는 의미로, (4-1) = 3 번째 인덱스에 있는 방향이동을 수행하면 됩니다.
dr,dc의 3번째 인덱스는 각각 (1,0)므로, 행은 1증가, 열은 그대로 인 남쪽이동이라는 것을 알 수 있습니다.
이동한 좌표가 지도 NxM 범위 안에 들어온다면, go함수를 실행하고, 범위 밖이라면, 다시 좌표를 원상복구합니다.(이동불가하니까!)
go함수에서 이제 처음에 구상한 주사위의 전개도의 활약이 나옵니다.
각 4가지 경우에 따라 주사위 면이 어떻게 바뀔지 case를 나눠서 그대로 구현해줍니다.
이동을 완료한 주사위가 있는 바닥칸에 적혀져 있는 숫자가 0인지 아닌지에 따라 주사위의 아래쪽(dice[-1])과 보드에 적혀져 있는 숫자(board[nr][nc])가 달라지므로 해당 작업을 구현해줍니다. 바닥칸에 적혀져 있는 숫자가 0이라면 바닥칸을 주사위의 아래쪽에 적혀져 있는 숫자로 대체하고, 보드에 적혀져 있는 숫자가 0이 아니라면, 주사위 아래쪽(dice[-1])의 숫자를 보드에 적혀져 있는 숫자(board[nr][nc])로 대체하고 바닥면은 다시 0으로 갱신하면 됩니다.
전개도 부분만 직접 그려보면서, 구현하려고 차근차근 풀이한다면 충분히 푸실 수 있으실 겁니다! 저도 구현은 항상 힘들지만 힘내보자구요!
이상 주사위 굴리기를 정리해봤습니다.
'컴퓨터 공부 > 📚 Baekjoon(백준)' 카테고리의 다른 글
[백준/알고리즘/python/java] 14502번 - 연구소 (4) | 2023.11.21 |
---|---|
[백준/알고리즘/python/java] 2852번 - NBA 농구 (1) | 2023.11.16 |
[백준/알고리즘/python/java] 1976번 - 여행 계획 (0) | 2022.12.11 |
[백준/알고리즘/python/java] 2309번 - 일곱 난쟁이 (0) | 2022.09.27 |
[백준/알고리즘/python/java] 11723번 - 집합 (0) | 2022.06.28 |