코테연습문제

[백준/Python] 14891 톱니바퀴

SI-AH 2023. 5. 28. 19:13

아... 문제가 너무 어려웠다;ㅅ;

혼자 풀어보다가 코드 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)은 제일 앞에 있던 요소가 제일 뒤로 이동하게됨.


처음 구현했던 코드는 기준 톱니바퀴 양 옆에 있는 톱니바퀴만 생각해서 틀렸는데,

양 옆뿐 아니라 모든 톱니바퀴에 대해 회전이 가능한지를 알아보려면 어떻게 해야할까 고민하다가 재귀함수를 이용해야겠다고 생각했습니다.