본문 바로가기
Problem Solving/Python

[백준]BOJ 14891: 톱니바퀴 - Python

by Kellang 2024. 4. 19.

14891번: 톱니바퀴 (acmicpc.net)

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

문제

위 링크 참조

풀이

설명이 불친절하고 매우 비직관적이므로 문제를 잘 읽어야 한다. 딱히 필요로 하는 알고리즘은 없고, 구현 능력 자체도 크게 요구하지 않는다. 그냥 문제를 이해하는것 자체가 이 문제의 가장 큰 난관이지만, 그렇다고 국어문제도 아닌게 애초에 문제가 말이 안된다.

 

이 문제에서 톱니바퀴는 절대로 현실의 톱니바퀴처럼 움직이지 않는다. 이전 톱니바퀴가 회전하면 다음 톱니바퀴도 회전해야할지 말아야 할지를 이미 돌아간 상태의 이전 톱니바퀴가 아닌 돌기 전의 이전 톱니바퀴의 상태로 판단해야 한다.

코드

class Gear():
    def __init__(self, stat):
        self.__stat = stat
        self.__top = 0
        self.__left = 6
        self.__right = 2

    def rotate(self, drct):
        self.__top = (self.__top - drct) % 8
        self.__left = (self.__left - drct) % 8
        self.__right = (self.__right - drct) % 8

    @property
    def top(self):
        return self.__stat[self.__top]
    @property
    def left(self):
        return self.__stat[self.__left]
    @property
    def right(self):
        return self.__stat[self.__right]

def left_shift(gear_num, drct):
    new_drct = drct * -1
    cur_gear = gear_num
    for next_gear in range(gear_num - 1, 0, -1):
        if gears[next_gear].right != gears[cur_gear].left:
            rotate_queue.append((next_gear, new_drct))
            cur_gear = next_gear
            new_drct *= -1
        else:
            break

def right_shift(gear_num, drct):
    new_drct = drct * -1
    cur_gear = gear_num
    for next_gear in range(gear_num + 1, 5):
        if gears[next_gear].left != gears[cur_gear].right:
            rotate_queue.append((next_gear, new_drct))
            cur_gear = next_gear
            new_drct *= -1
        else: 
            break

gear1 = Gear(list(map(int, input())))
gear2 = Gear(list(map(int, input())))
gear3 = Gear(list(map(int, input())))
gear4 = Gear(list(map(int, input())))
gears = [None, gear1, gear2, gear3, gear4]

k = int(input())
answer = 0

rotate_queue = []

for _ in range(k):
    num, drct = map(int, input().split())
    rotate_queue.append((num, drct))
    left_shift(num, drct)
    right_shift(num, drct)
    for g, d in rotate_queue:
        gears[g].rotate(d)
    rotate_queue = []

rank = 1
for idx in range(1, 5):
    answer += gears[idx].top * rank
    rank *= 2

print(answer)