78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
# 햄버거 분배
|
|
|
|
import sys
|
|
from collections import deque
|
|
|
|
input = sys.stdin.readline
|
|
|
|
def clear_left(d, i, k):
|
|
while len(d) >= 1 and d[0][0] < i - (k):
|
|
d.popleft()
|
|
return
|
|
|
|
def clear_right(d, i, k):
|
|
while len(d) >= 1 and d[-1][0] < i - (k):
|
|
d.pop()
|
|
return
|
|
|
|
def manage_h(d, i, t, result):
|
|
if len(d) >= 1 and d[-1][1] == "P":
|
|
d.pop()
|
|
result += 1
|
|
else:
|
|
d.append((i, t))
|
|
return result
|
|
|
|
def manage_p(d, i, t, result):
|
|
if len(d) >= 1 and d[0][1] == "H":
|
|
d.popleft()
|
|
result += 1
|
|
else:
|
|
d.appendleft((i, t))
|
|
return result
|
|
|
|
MANAGEMENT = {
|
|
"H": manage_h,
|
|
"P": manage_p
|
|
}
|
|
|
|
def solution():
|
|
n, k = map(int, input().rstrip().split())
|
|
|
|
table = input().rstrip()
|
|
|
|
d = deque()
|
|
|
|
result = 0
|
|
for i, t in enumerate(table):
|
|
clear_left(d, i, k)
|
|
clear_right(d, i, k)
|
|
manager = MANAGEMENT.get(t, None)
|
|
|
|
if not manager:
|
|
return -1
|
|
|
|
result = manager(d, i, t, result)
|
|
|
|
print(result)
|
|
|
|
return
|
|
|
|
|
|
solution()
|
|
|
|
"""
|
|
걸린 시간: 35분
|
|
|
|
시간 복잡도: deque의 길이를 k로 유지하면서 테이블에 있는 하나의 요소는 deque에 1번만 들어오거나 나가기 때문에
|
|
한 요소 당 시간 복잡도는 O(1)이고 전체 요소에 대해서 진행하기 때문에 전체 시간복잡도는 O(n)이다.
|
|
|
|
해설: P, H가 짝을 지어서 사라지면 된다고 생각하여 스택을 떠올렸고, 오래된 H나 P는 선택할 수 없게 지워버리는 방법을 생각했을 때
|
|
큐가 생각나서, 합쳐서 deque를 사용하기로 하였다.
|
|
처음에는 오래된 것들을 나가는 방향을 popleft, P/H가 들어오는 곳은 append, 짝을 이뤄서 나가는 방향을 pop으로 생각했는데,
|
|
이러면 과거 H를 P가 먹을 수 있는 상황에서 가장 최신 H만 먹기 때문에 최선이 아니다.
|
|
따라서 P는 들어오는 것과 짝 맞춰서 나가는 것을 왼쪽, H는 오른쪽으로 함으로써 우선순위를 오래 기다린 사람과 오래된 햄버거로 하였다.
|
|
그리고 이번에 들어오는 요소는 k 범위 이전 것들과는 전혀 상호작용할 수 없으므로 매번 clear를 왼쪽, 오른쪽을 다 해준다.
|
|
|
|
참고: len(list, deque, set, dict)들 모두 원소의 개수를 따로 저장하고 있기 때문에 O(1)이다.
|
|
""" |