[백준/Python] 14891 톱니바퀴
아... 문제가 너무 어려웠다;ㅅ;
혼자 풀어보다가 코드 100줄 넘어가는 거 보고, 안되겠다 싶어서 구글링 했는데
사실 아직도 100% 이해하진 못한 거 같음.... 다시 혼자 풀어보라고 하면 못 풀 거 같다;ㅅ;
그래서 오늘 설명은 약간 읽으면서도 뭔소린가 싶을 수 있습니다..
그치만 최대한 자세히 써보겠습니다.....!!
일단 이 문제에서 가장 중요한 건 재귀함수인 것 같고,
deque를 사용한 이유는, 톱니바퀴를 시계/반시계 방향으로 회전할 때, 양 끝 값을 넣고 빼야했기 때문에 이에 용이한 deque를 사용함!!!
from collections import deque
# 시계 방향으로 회전
def clock(g, c):
# 기준 톱니바퀴 오른쪽에 있는 톱니바퀴가 톨아가는지 안돌아가는지 확인
if g <= 3 and gears[g][6] != gears[g - 1][2]:
clock(g + 1, -c) # 인접한 톱니바퀴는 반대로 돌아감
gears[g].rotate(c) # 기준이 되는 톱니바퀴 회전
# 반시계 방향으로 회전
def counterClock(g, c):
# 기준 톱니바퀴 왼쪽에 있는 톱니바퀴가 톨아가는지 안돌아가는지 확인
if g >= 0 and gears[g][2] != gears[g + 1][6]:
counterClock(g - 1, -c) # 인접한 톱니바퀴는 반대로 돌아감
gears[g].rotate(c) # 기준이 되는 톱니바퀴 회전
# gears에 각 톱니바퀴에 대한 정보를 담음
gears = [deque(input()) for _ in range(4)]
K = int(input())
for _ in range(K):
g, c = map(int, input().split())
g = g - 1 # gears[0]은 1번 톱니바퀴, gears[1]은 2번 톱니바퀴, gears[2]은 3번 톱니바퀴, gears[3]은 4번 톱니바퀴
counterClock(g - 1, -c) # 기준 톱니바퀴의 왼쪽에 있는 톱니바퀴에 대해
clock(g + 1, -c) # 기준 톱니바퀴의 오른쪽에 있는 톱니바퀴에 대해
gears[g].rotate(c)
answer = 0
if gears[0][0] == '1':
answer += 1
if gears[1][0] == '1':
answer += 2
if gears[2][0] == '1':
answer += 4
if gears[3][0] == '1':
answer += 8
print(answer)
풀이과정
1. 자.. 일단 먼저 gears에 각 톱니바퀴에 대한 정보를 담아줍니다
2. 그 다음 g와 c를 받는데( g: 몇 번 톱니바퀴 / c: 시계방향 or 반시계방향 )
g = g-1을 해줘서 사용하기 쉽게 해줍니다. ( g=1이면, 0번 톱니바퀴인데, 그냥 헷갈리지 않게 하려고)
3. 회전시킬 톱니바퀴와 인접한 톱니바퀴를 회전시킬 수 있는지부터 확인해야합니다.
4. 만약 회전시킬 수 있다면, 다시 한 번 인접한 톱니바퀴의 옆에 있는 톱니바퀴도 회전시킬 수 있는지 확인해야합니다.
5. 이렇게 계속 확인하며 회전시키기 위해 재귀함수를 사용했고,
5-1. 모든 인접한 톱니바퀴는 서로 반대방향으로 회전하기에, rotate에 인자로 넣는 값에 계속 -를 붙여줘야 합니다.
6. 마지막에 기준이 되는 톱니바퀴도 회전시켜주면, 원하는 값을 얻을 수 있습니다.
알게 된 것
1. .rotate()
deque의 연산 중에는 rotate()라고 하는 연산이 존재.
roate(1) 또는 roate(-1) 으로 사용이 가능한데,
rotate(1)은 시계방향,
rotate(-1)은 반시계방향으로 deque를 회전시키는 것 처럼 사용할 수 있음
즉, rotate(1)은 제일 뒤에 있던 요소가 제일 앞으로 이동하고,
rotate(-1)은 제일 앞에 있던 요소가 제일 뒤로 이동하게됨.
처음 구현했던 코드는 기준 톱니바퀴 양 옆에 있는 톱니바퀴만 생각해서 틀렸는데,
양 옆뿐 아니라 모든 톱니바퀴에 대해 회전이 가능한지를 알아보려면 어떻게 해야할까 고민하다가 재귀함수를 이용해야겠다고 생각했습니다.