[BOJ] 14891. 톱니바퀴

Jimeaning·2023년 7월 17일
0

코딩테스트

목록 보기
113/143

Python3

문제

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

키워드

  • 구현
  • 시뮬레이션

문제 풀이

문제 요구사항

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 일렬로 놓여져 있다.
톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴가 1번, 그 오른쪽은 2번, 그 오른쪽은 3번, 가장 오른쪽 톱니바퀴는 4번이다.

또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다.

이때, 톱니바퀴를 총 K번 회전시키려고 한다.
(톱니바퀴의 회전은 한 칸을 기준. 회전은 시계 방향과 반시계 방향 두 가지.)

톱니바퀴 A를 회전할 때, 그 옆에 있는 톱니바퀴 B와 서로 맞닿은 톱니의 극이 다르다면, B는 A가 회전한 방향과 반대방향으로 회전하게 된다.

톱니바퀴의 초기 상태와 톱니바퀴를 회전시킨 방법이 주어졌을 때, 최종 톱니바퀴의 상태를 구하는 프로그램

변수 및 함수 설명

wheel: 바퀴 상태 (12시방향부터 시계방향 순서대로 주어진다. N극은 0, S극은 1로 나타나있다.)
score: 네 톱니바퀴 점수의 합
k: 회전 횟수 (1 ≤ K ≤ 100)
num, dir: num은 회전시킨 톱니바퀴의 번호, dir은 방향이다. 방향이 1인 경우는 시계 방향이고, -1인 경우는 반시계 방향이다.

left(start, dirs): 왼쪽 톱니 조사 함수
right(start, dirs): 오른쪽 톱니 조사 함수

풀이

(입력 및 선언)

  • 총 네 개의 톱니바퀴를 입력받고 deque을 사용해 wheel 리스트에 저장한다.
    (rotate 함수를 사용하기 위함)
  • 회전 횟수인 k를 입력받고 총 k번 반복한다.
  • 회전시킬 톱니바퀴 번호와 방향을 입력받는다.
  • 이때 톱니바퀴 번호는 1부터 시작하지만, 리스트는 0부터 시작하므로 -1을 해준다.
  • left 함수로 왼쪽 톱니를 조사하고, right 함수로 오른쪽 톱니를 조사할 것이다.
  • 인자는 왼쪽 조사일 때는 현재 톱니바퀴의 왼쪽 톱니(num-1)과 -dir이다.
  • 오른쪽 조사일 때는 현재 톱니바퀴의 오른쪽 톱니(num+1)과 -dir이다.
  • -dir인 이유는 회전할 톱니번호가 회전하는 방향의 반대방향으로 회전해야 하기 때문
  • 현재 톱니바퀴도 dir 방향대로 rotate 시킨다.

(왼쪽 톱니바퀴 조사)

  • 만약 톱니가 0보다 작다면 (즉, 첫 번째 톱니를 돌리는 것이라면) 확인할 필요 없다.
  • 만약 톱니의 2번째 원소와 현재 톱니의 6번째 원소가 다르다면, 그 왼쪽 톱니바퀴도 조사한다.
  • 그리고 현재 톱니를 방향대로 돌린다

(오른쪽 톱니바퀴 조사)

  • 만약 톱니가 3보다 크다면 (즉, 마지막 톱니를 돌리는 것이라면) 확인할 필요 없다.
  • 만약 톱니의 6번째 원소와 이전 톱니의 2번째 원소가 다르면, 그 오른쪽 톱니바퀴도 조사한다.
  • 현재 톱니를 방향대로 돌린다.

(최종 점수 출력)

  • 만약 첫 번째 톱니가 1로 시작하면 1점을 누적한다.
  • 만약 두 번째 톱니가 1로 시작하면 2점을 누적한다.
  • 만약 세 번째 톱니가 1로 시작하면 4점을 누적한다.
  • 만약 네 번째 톱니가 1로 시작하면 8점을 누적한다.
  • 최종 스코어를 출력한다.

최종 코드

from collections import deque

wheel = []
score = 0

def left(start, dirs):
    if start < 0:
        return
    if wheel[start][2] != wheel[start+1][6]:
        left(start-1, -dirs)
        wheel[start].rotate(dirs)

def right(start, dirs):
    if start > 3:
        return
    if wheel[start][6] != wheel[start-1][2]:
        right(start+1, -dirs)
        wheel[start].rotate(dirs)

for _ in range(4):
    wheel.append(deque(list(input())))

k = int(input())

for _ in range(k):
    num, dir = map(int, input().split())
    num -= 1

    left(num-1, -dir) # 왼쪽 조사
    right(num+1, -dir) # 오른쪽 조사
    wheel[num].rotate(dir)

if wheel[0][0] == '1':
    score += 1
if wheel[1][0] == '1':
    score += 2
if wheel[2][0] == '1':
    score += 4
if wheel[3][0] == '1':
    score += 8

print(score)

피드백

deque을 사용해 rotate 함수를 활용하고 재귀 함수로 푸는 방법이 있었다.
역시 쉽지 않다.. 다시 풀어봐야 할 듯 하다.

profile
I mean

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

좋은 글 잘 읽었습니다, 감사합니다.

답글 달기