알고리즘/문제풀이
[Python] 백준 15961, 2531 회전 초밥
정찡이
2021. 7. 17. 21:27
728x90
1. 문제 링크
https://www.acmicpc.net/problem/15961
15961번: 회전 초밥
첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 3,000,000, 2 ≤ d ≤ 3,000, 2
www.acmicpc.net
https://www.acmicpc.net/problem/2531
2531번: 회전 초밥
첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 30,000, 2 ≤ d ≤ 3,000, 2 ≤
www.acmicpc.net
2. 문제 요약
- k개의 접시 연속으로 먹기 ⇒ 슬라이딩 윈도우
- 1 조건을 만족한 경우, 쿠폰에 적힌 초밥 먹기 가능
⇒ 먹을 수 있는 초밥 가짓수의 최댓값 구하기

3. 아이디어 정리
- 원형이니 회전초밥 리스트를 2개 이어준다.
- k개의 접시를 연속으로 먹기 위해 슬라이딩 윈도우를 적용한다.
- dict를 이용하여 현재까지 먹은 초밥의 종류를 저장한다.
4. 문제 풀이
4-1. 내 풀이
"""
손님이 먹을 수 있는 초밥의 가짓수의 최댓값
"""
import sys
from collections import defaultdict
# 접시 수, 초밥 가짓수, 연속해서 먹는 접시 수, 쿠폰 번호
n, d, k, c = map(int, sys.stdin.readline().split())
arr = [int(sys.stdin.readline()) for _ in range(n)]
arr.extend(arr) # 원형이라서 2개를 이어준다.
left = 0
right = 0
dict_ = defaultdict(int)
result = 0
dict_[c] += 1 # 보너스는 무조건 먹기
# 1. 처음에 k 구간만큼 먹기
while right < k:
dict_[arr[right]] += 1
right += 1
# 2. 슬라이딩 윈도우 적용
while right < len(arr):
result = max(result, len(dict_))
# 1. 맨 왼쪽 초밥 제거
dict_[arr[left]] -= 1
if dict_[arr[left]] == 0: # 삭제된 왼쪽 초밥이 0 이면 dict 삭제
del dict_[arr[left]]
# 2. 오른쪽 초밥 추가하기
dict_[arr[right]] += 1
# 왼쪽 위치 + 1
left += 1
# 오른쪽 위치 + 1
right += 1
print(result)
5. 결론
- 슬라이딩 윈도우 문제
- 원형인 경우에 2개의 리스트를 이어줘서 해결 가능
반응형