백준 1021번 - 회전하는 큐

회전하는 큐 문제 바로 가기

풀이 날짜: 2026-03-17

baekjoon 알고리즘 문제 풀이

풀이 코드


from collections import deque

n,m = map(int, input().split())
num = list(map(int, input().split()))

q = deque(range(1,n+1))
count = 0

for i in num:
    idx = q.index(i)

    if idx <= len(q) // 2:
        q.rotate(-idx)
        count += idx
    else:
        q.rotate(len(q) - idx)
        count += len(q) - idx

    q.popleft()
print(count)
  

문제 접근

이 문제는 1부터 N까지의 수가 들어있는 큐에서 특정 수들을 순서대로 꺼낼 때, 큐를 왼쪽 또는 오른쪽으로 회전시키는 최소 횟수를 구하는 문제이다. 단순히 값을 제거하는 것이 아니라, 원하는 값을 큐의 맨 앞까지 이동시킨 후 제거해야 한다.


핵심 아이디어

각 단계마다 현재 큐에서 목표 값의 위치를 확인한 뒤, 왼쪽으로 이동할지 오른쪽으로 이동할지를 결정하는 것이 핵심이다. 큐의 앞쪽에 가까운 경우에는 왼쪽 회전이, 뒤쪽에 가까운 경우에는 오른쪽 회전이 더 효율적이다. 즉, 현재 위치(index)를 기준으로 왼쪽 이동 횟수와 오른쪽 이동 횟수를 비교하여 더 작은 값을 선택하는 방식으로 진행한다.


회전 기준 정리

현재 큐에서 타겟의 위치를 idx라고 할 때 다음과 같이 했다.

  • 왼쪽 이동 횟수: idx
  • 오른쪽 이동 횟수: len(queue) - idx

deque와 rotate 활용

이 문제는 양방향에서 원소를 추가/삭제할 수 있는 deque 자료구조를 사용하는 것이 핵심이다. 특히 rotate() 함수를 활용하면 반복문 없이도 큐를 한 번에 회전시킬 수 있어 코드가 간결해진다.

  • rotate(-k) → 왼쪽으로 k칸 이동
  • rotate(k) → 오른쪽으로 k칸 이동

내가 헷갈렸던 부분

처음에는 특정 숫자를 꺼내기 위해 “몇 칸 이동해야 하는지”를 직접 이동 거리처럼 생각했지만, 실제로는 큐 자체를 회전시켜서 값을 앞으로 가져오는 개념이었다. 또한 오른쪽 이동 횟수가 단순히 거리로 계산되는 것이 아니라 len - idx로 계산된다는 점이 처음에는 직관적이지 않았지만, 큐가 원형 구조처럼 동작한다고 생각하면 쉽게 이해할 수 있었다.