[문제]
https://www.acmicpc.net/problem/14499
주사위를 굴릴 때마다 주사위가 어떻게 변화하는지 시뮬레이션하는 문제입니다.
주사위를 "굴린다." 라는 표현에서 값들이 회전한다는 느낌을 받았고, 자연스럽게 Deque 자료구조를 떠올릴 수 있었습니다.
[초기화]
def __init__(self):
self.n, self.m, self.y, self.x, self.k = map(int, input().split())
self.grid = [list(map(int, input().split())) for _ in range(self.n)]
self.commands = list(map(lambda x: int(x) - 1, input().split()))
self.directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
self.col = deque([0, 0, 0, 0])
self.row = deque([0, 0, 0, 0])
입력은 x, y 순으로 주어지는데, 저는 세로축을 표현할 때 y로 표현하는 것이 익숙해, 변수명을 반대로 지정하였습니다.
col, row는 주사위의 전개도를 펼쳤을 때 방향을 나타냅니다.
문제의 예시와 상관없이 임의의 전개도를 나타내면 위 그림과 같습니다.
또한 이를 저료구조로 표현하게되면 아래 그림과 같습니다.
주의 깊게 보시면, 1번 인덱스와 4번 인덱스의 값이 같다는 것을 알 수 있습니다. 이들은 각각 바닥과 위를 나타내며, 주사위를 굴렸을 때 실질적으로 영향을 받는 값들입니다.
예를 들어 row 기준으로 봤을 때, 오른쪽으로 주사위를 굴리면 5, 2, 6, 4 → 2, 6, 4, 5로 변경되며 값들이 하나씩 밀린 것을 확인할 수 있습니다.
이렇게 된다면, col은 1, 2, 3, 4 → 1, 6, 3, 5로 변경되며 row의 1, 3번 인덱스를 따르게 됩니다.
반대로 굴리는 상황에서도 동일하게 적용됩니다.
글이 이해가 되지 않는다면, 종이에 직접 그려보신다면 보다 쉽게 이해할 수 있을 것입니다.
[풀이]
def solve(self):
for command in self.commands:
dy, dx = self.directions[command]
my = self.y + dy
mx = self.x + dx
if 0 <= my < self.n and 0 <= mx < self.m:
self.y = my
self.x = mx
if command <= 1:
self.row.rotate(-1 if command == 0 else 1)
self.col[1] = self.row[1]
self.col[3] = self.row[3]
self.setup()
else:
self.col.rotate(1 if command == 2 else -1)
self.row[1] = self.col[1]
self.row[3] = self.col[3]
self.setup()
print(self.col[-1])
주사위를 굴리는 로직입니다.
이동하려는 칸이 격자를 벗어나지 않았을 때만 주사위를 회전시킵니다.
주사위는 주어진 명령에 맞춰 회전 방향을 결정하게 되고, 위에서 설명한 풀이대로 1, 3번 인덱스의 값만 변경합니다.
def setup(self):
if self.grid[self.y][self.x] == 0:
self.grid[self.y][self.x] = self.col[1]
else:
self.col[1] = self.grid[self.y][self.x]
self.row[1] = self.grid[self.y][self.x]
self.grid[self.y][self.x] = 0
주사위가 굴려지고 나서는 주어진 조건을 처리합니다.
해당 로직은 문제의 다음 조건에 해당합니다.
[전체 코드]
from collections import deque
class Main:
def __init__(self):
self.n, self.m, self.y, self.x, self.k = map(int, input().split())
self.grid = [list(map(int, input().split())) for _ in range(self.n)]
self.commands = list(map(lambda x: int(x) - 1, input().split()))
self.directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
self.col = deque([0, 0, 0, 0])
self.row = deque([0, 0, 0, 0])
def setup(self):
if self.grid[self.y][self.x] == 0:
self.grid[self.y][self.x] = self.col[1]
else:
self.col[1] = self.grid[self.y][self.x]
self.row[1] = self.grid[self.y][self.x]
self.grid[self.y][self.x] = 0
def solve(self):
for command in self.commands:
dy, dx = self.directions[command]
my = self.y + dy
mx = self.x + dx
if 0 <= my < self.n and 0 <= mx < self.m:
self.y = my
self.x = mx
if command <= 1:
self.row.rotate(-1 if command == 0 else 1)
self.col[1] = self.row[1]
self.col[3] = self.row[3]
self.setup()
else:
self.col.rotate(1 if command == 2 else -1)
self.row[1] = self.col[1]
self.row[3] = self.col[3]
self.setup()
print(self.col[-1])
problem = Main()
problem.solve()
조건에 맞게 분기처리로도 풀 수 있겠지만, 제 기준 deque을 이용한 rotate가 머릿속에 직관적으로 그려져 해당 방식으로 풀이를 진행해 보았습니다.
'Algorithm > 백준' 카테고리의 다른 글
[백준: Python] 21608 - 상어 초등학교 (0) | 2025.02.14 |
---|---|
[백준: Python] 1937 - 욕심쟁이 판다 (0) | 2025.02.08 |
[백준: Python] 2458 - 키 순서 (0) | 2024.12.05 |
[백준: Java] 7490 - 0 만들기 (0) | 2024.11.26 |
[백준: Python] 2109 - 순회강연 (0) | 2024.11.25 |