Algorithm

[백준] 톱니바퀴 14891번 (python) 구현

salmon16 2024. 9. 8. 16:48

출처 : https://www.acmicpc.net/problem/14891

 

풀이 방법

구현 문제이므로 문제 파악이 중요했다.

구현해야 할 부분을 함수별로 하나씩 나누어 구현했다.

또한 케이스를 나누는 것에 집중했다.

 

크게 만약 각 돌리기 명령에서 시작인 경우와 아닌 경우로 나누었다.

  1. 돌리기 시작인 톱니바퀴
    1. 양 끝에 있는 경우
      1. 1번 톱니면 오른쪽만 4번 톱니면 왼쪽만 체크한다.
    2. 중간에 있는 경우
      1. 양 쪽을 다 확인한다.
  2. 돌리기 시작이지 않는 톱니바퀴
    1. 왼쪽만 확인
    2. 오른쪽만 확인

위와 같은 경우로 나눌 수 있다.

 

구현해야 할 함수를 생각해 보자

 

 

1. 톱니 돌리는 함수

먼저 톱니 돌리기 위해 나는 톱니바퀴의 제일 위(12시 방향) 인덱스를 저장해 시계방향으로의 회전은 인덱스에 -1 반 시계방향은 +1을 해주고 % 8 연산을 통해 관리했다.

 

2. 오른쪽 체크 함수

현재 톱니바퀴의 제일 위 인덱스에서 +2를 해준 인덱스와 오른 쪽 톱니바퀴의 +6 인덱스를 비교해서 둘이 다르다면 반대 방향으로 회전했다.

 

3. 왼쪽 체크 함수

현재 톱니바퀴의 제일 위 인덱스에서 +6을 해준 인덱스와 왼쪽 톱니바퀴의 +2 인덱스를 비교해서 둘이 다르다면 반대 방향으로 회전했다.

 

4. 회전 함수

위에서 나눈 케이스에 따라 cnt로 3인 경우 양 쪽 다 확인(시간 톱니만 해당) 

1인 경우 왼쪽만 확인 2인 경우 오른쪽만 확인한다.

 

위에 나는 케이스로 구현하면 된다.

 

## 0이면 N 1이면 S
## 극이 서로 다르면 반대 방향으로 움직인다. 
cogwheel = [[]] ## 톱니바퀴  인덱스 맞추기 위해 빈 배열 추가
wheel_head = [0, 0, 0, 0, 0] ## 톱니바퀴의 제일 위를 뜻한다. 인덱스를 맞추기 위해 0 하나 추가 
for _ in range(4):
    arr = list(map(int, input()))
    cogwheel.append(arr)

N = int(input())
command = []

for i in range(N): ## 이동 입력 받기 
    a, b = map(int, input().split()) ## 1이 시계방향이므로 제일 머리의 인덱스를 옮김을 통해 회전하려면 반대 부호를 가져야 한다. 
    command.append([a, -b])


## 움직이는 함수 인덱스 나머지 9 오른 쪽 +2 왼쪽 +6 
## 1이 시계방향 -1 반 시계 방향
def move(dir, idx, cnt):
    # 인접한 톱니바퀴와의 맞물림을 체크하는 함수
    def check_left(idx):
        return cogwheel[idx][(wheel_head[idx] + 6) % 8] != cogwheel[idx - 1][(wheel_head[idx - 1] + 2) % 8]

    def check_right(idx):
        return cogwheel[idx][(wheel_head[idx] + 2) % 8] != cogwheel[idx + 1][(wheel_head[idx + 1] + 6) % 8]

    # 왼쪽 톱니바퀴와 맞물림 체크 및 회전
    if cnt in (1, 3) and idx > 1 and check_left(idx):
        move(-dir, idx - 1, 1)

    # 오른쪽 톱니바퀴와 맞물림 체크 및 회전
    if cnt in (2, 3) and idx < 4 and check_right(idx):
        move(-dir, idx + 1, 2)

    # 현재 톱니바퀴 회전
    wheel_head[idx] = (wheel_head[idx] + dir) % 8
## 1이면 시계 방향 -1 이면 반시계 방향 
## idx 2번 오른쪽 idx 6번이 왼쪽
for idx, dir in command: ## 톱니바퀴의 인덱스, 움질일 방향
    ## 움직일 톱니의 양 옆을 확인한다. 
    move(dir, idx, 3)

ans = 0 
if cogwheel[1][wheel_head[1] % 8] == 1:
     ans += 1
if cogwheel[2][wheel_head[2] % 8] == 1:
     ans += 2
if cogwheel[3][wheel_head[3] % 8] == 1:
     ans += 4
if cogwheel[4][wheel_head[4] % 8] == 1:
     ans += 8
print(ans)