[BOJ] 14891번 톱니바퀴 (Python) [삼성 SW 역량 테스트 기출 문제]

천호영·2023년 2월 1일
0

알고리즘

목록 보기
61/100
post-thumbnail

문제

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

풀이

톱니바퀴를 회전한 후에 극이 같은지 비교한다고 처음에 문제를 잘못 이해했었다. 문제를 읽을때 시간을 많이 들여서 처음에 정확하게 이해하자.

문제에서 예시에 대한 부분은 확실하게 이해하고 넘어가야 한다.

처음 AC받은 풀이는 다음과 같다. 각각의 톱니바퀴에 대해 함수를 작성했다.

from collections import deque
CLOCKWISE, COUNTER_CLOCKWISE = 1, -1

def move(queue, direction):
  if direction == CLOCKWISE: # 시계 방향
    queue.appendleft(queue.pop())
  else: # 반시계 방향
    queue.append(queue.popleft())

def queue1_move(direction, visited):
  #print('queue1 이동')
  visited[1] = True
  if not visited[2] and queue1[2] != queue2[6]: # 2번 톱니바퀴
    queue2_move(direction*(-1), visited)
  move(queue1, direction)

def queue2_move(direction, visited):
  #print('queue2 이동')
  visited[2] = True
  if not visited[1] and queue1[2] != queue2[6]: # 1번 톱니바퀴
    queue1_move(direction*(-1), visited)
  if not visited[3] and queue2[2] != queue3[6]: # 3번 톱니바퀴
    queue3_move(direction*(-1), visited)
  move(queue2, direction)

def queue3_move(direction, visited):
  #print('queue3 이동')
  visited[3] = True
  if not visited[2] and queue2[2] != queue3[6]: # 2번 톱니바퀴
    queue2_move(direction*(-1), visited)
  if not visited[4] and queue3[2] != queue4[6]: # 4번 톱니바퀴
    queue4_move(direction*(-1), visited)
  move(queue3, direction)

def queue4_move(direction, visited):
  #print('queue4 이동')
  visited[4] = True
  if not visited[3] and queue3[2] != queue4[6]: # 3번 톱니바퀴
    queue3_move(direction*(-1), visited)
  move(queue4, direction)

queue1 = deque(map(int, list(input())))
queue2 = deque(map(int, list(input())))
queue3 = deque(map(int, list(input())))
queue4 = deque(map(int, list(input())))

K = int(input())
for _ in range(K):
  queue_num, direction = map(int, input().split())
  visited = [False]*5
  if queue_num == 1:
    queue1_move(direction, visited)
  elif queue_num == 2:
    queue2_move(direction, visited)
  elif queue_num == 3:
    queue3_move(direction, visited)
  else:
    queue4_move(direction, visited)
  #print(queue1)
  #print(queue2)
  #print(queue3)
  #print(queue4)

# 점수 합 구해서 출력
print(queue1[0]*1+queue2[0]*2+queue3[0]*4+queue4[0]*8)
  • 원형큐를 그냥 직접 append, pop해서 구현했는데 더 잘 쓸 수 있는 방법이 있는지 찾아봐야겠다.
    => deque에 rotate라는게 존재한다!(참조)
>>> from collections import deque
>>> test = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> test = deque(test)
>>> test.rotate(2) 
>>> result = list(test)
>>> result
[8, 9, 1, 2, 3, 4, 5, 6, 7]

이를 톱니바퀴별 함수가 아닌 하나의 함수로 리팩토링한 코드는 다음과 같다.

from collections import deque
CLOCKWISE, COUNTER_CLOCKWISE = 1, -1

def move(queue, direction):
  if direction == CLOCKWISE: # 시계 방향
    queue.appendleft(queue.pop())
  else: # 반시계 방향
    queue.append(queue.popleft())

def is_valid(q_num, visited):
  if 1<=q_num<=4 and not visited[q_num]: # 1~4번에 해당하면서 돌린적(방문한적) 없을때
    return True
  return False

def queue_move(q_num, direction, visited):
  visited[q_num] = True # 방문처리

  # 왼쪽 톱니바퀴
  if is_valid(q_num-1, visited) and queues[q_num-1][2] != queues[q_num][6]:
    queue_move(q_num-1, direction*(-1), visited)   

  # 오른쪽 톱니바퀴
  if is_valid(q_num+1, visited) and queues[q_num][2] != queues[q_num+1][6]:
    queue_move(q_num+1, direction*(-1), visited)
      
  move(queues[q_num], direction) # 돌리기 이전 기준으로 왼쪽, 오른쪽 체크하므로 맨 마지막에 돌리기

queue1 = deque(map(int, list(input())))
queue2 = deque(map(int, list(input())))
queue3 = deque(map(int, list(input())))
queue4 = deque(map(int, list(input())))
queues = [None, queue1, queue2, queue3, queue4] # 인덱싱 번호랑 같게 편하게 하려고 1부터

K = int(input())
for _ in range(K):
  queue_num, direction = map(int, input().split())
  visited = [False]*5
  queue_move(queue_num, direction, visited)

# 점수 합 구해서 출력
print(queue1[0]*1+queue2[0]*2+queue3[0]*4+queue4[0]*8)
profile
성장!

0개의 댓글