오늘 문제는 덱 자료 구조의 기본 기능들을 직접적으로 활용하는 문제입니다.
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 128 MB | 47894 | 28823 | 23514 | 61.762% |
첫째 줄에 큐의 크기 N과 뽑아내려고 하는 수의 개수 M이 주어진다. N은 50보다 작거나 같은 자연수이고, M은 N보다 작거나 같은 자연수이다. 둘째 줄에는 지민이가 뽑아내려고 하는 수의 위치가 순서대로 주어진다. 위치는 1보다 크거나 같고, N보다 작거나 같은 자연수이다.
첫째 줄에 문제의 정답을 출력한다.
10 3
1 2 3
0
10 3
2 9 5
8
32 6
27 16 30 11 6 23
59
10 10
1 6 3 2 7 9 8 4 10 5
14
이 문제는 양방향 순환 큐를 활용하는 문제로, 주어진 위치의 원소를 큐에서 꺼낼 때 최소한의 이동 횟수로 원소를 뽑아내는 것이 목표입니다. 큐는 덱(deque) 자료 구조를 활용하여 양쪽에서 자유롭게 원소를 추가하거나 제거할 수 있으며, rotate()
메서드를 통해 왼쪽 또는 오른쪽으로 회전할 수 있습니다.
큐에서 원소를 꺼낼 때, 가능한 3가지 연산 중 2번(왼쪽 회전)과 3번(오른쪽 회전)의 횟수를 최소화하는 것이 중요합니다.
rotate()
메서드를 사용하여 큐를 회전시킵니다.import sys
from collections import deque
# 입력 받기
N, M = map(int, sys.stdin.readline().split())
queue = deque([i + 1 for i in range(N)]) # 1부터 N까지의 숫자를 큐에 저장
position = list(map(int, sys.stdin.readline().split())) # 뽑아내려는 숫자들의 리스트
cnt = 0 # 회전 연산 횟수를 저장할 변수
for i in position:
while True:
if queue[0] == i:
queue.popleft() # 첫 번째 원소가 목표하는 값일 때, 그냥 꺼냄
break
else:
# 왼쪽 회전이 더 효율적인 경우
if queue.index(i) <= len(queue) // 2:
while queue[0] != i:
queue.rotate(-1) # 왼쪽으로 한 칸 회전
cnt += 1
# 오른쪽 회전이 더 효율적인 경우
else:
while queue[0] != i:
queue.rotate(1) # 오른쪽으로 한 칸 회전
cnt += 1
# 결과 출력
print(cnt)
N
과 뽑아낼 원소의 개수 M
을 입력받습니다.popleft()
로 큐에서 제거합니다.rotate()
메서드로 왼쪽 또는 오른쪽으로 회전시킵니다.cnt
를 출력합니다.이 문제에서 큐의 크기 N은 최대 50이므로, 각 회전 연산은 최대 50번의 연산을 필요로 합니다. M개의 원소를 처리하므로, 최악의 경우에도 시간 복잡도는 , 즉 입니다. 이 시간 복잡도는 문제의 제한 내에서 충분히 해결 가능합니다.
이번 문제는 덱(deque) 자료 구조의 핵심 기능인 양방향 회전을 활용하는 문제로, 효율적인 연산을 통해 큐의 원소를 뽑아내는 과정에서 최소한의 연산 횟수를 요구했습니다. 특히, rotate()
메서드를 사용하여 큐를 왼쪽 또는 오른쪽으로 회전시키는 방법을 통해 문제를 해결할 수 있었으며, 이를 통해 덱의 장점을 실감할 수 있었습니다.
이번 풀이를 통해 덱의 활용법과 더불어, 어떻게 하면 효율적인 알고리즘을 설계할 수 있는지에 대한 감각을 익힐 수 있었습니다. 평소에 스택이나 큐 문제를 풀때도 collections모듈의 deque 클래스를 적극적으로 활용했는데, 이번 문제는 완전히 덱 자료 구조 자체를 활용하는 문제여서 신선했습니다.
다음에 또 다른 문제로 찾아오겠습니다.
Keep Going!! ⭐