728x90
반응형
백준 2531번. 회전 초밥 (투포인터)
1. 문제
https://www.acmicpc.net/problem/2531
회전 초밥집에서 연속된 접시 k
개를 선택할 때, 가장 다양한 종류의 초밥을 먹을 수 있는 경우의 수를 구하는 문제이다. 단, 이벤트로 제공되는 쿠폰 초밥 c
를 하나 추가로 먹을 수 있다.
2. 풀이 (문제 접근 방법)
- 슬라이딩 윈도우 기법 활용
- 한 번에
k
개의 초밥을 선택하는 방식이므로, 윈도우를 이동하며 가능한 경우를 탐색한다.
- 한 번에
- 중복된 초밥 개수 관리
collections.Counter
를 사용하여 현재 윈도우 내 초밥의 개수를 관리한다.
- 쿠폰 초밥 고려
- 선택한 초밥에 쿠폰 초밥
c
가 포함되지 않았다면 추가하여 최대값을 계산한다.
- 선택한 초밥에 쿠폰 초밥
3. 코드 구현
import sys
import collections
input = sys.stdin.readline
n, d, k, c = map(int, input().split())
sushi = [int(input()) for _ in range(n)]
sushi.extend(sushi[:k-1]) # 원형 리스트 처리
s, e = 0, k
temp = collections.Counter(sushi[0:k]) # 초기 윈도우 설정
max_cnt = len(temp) + (1 if c not in temp else 0) # 쿠폰 초밥 고려
while s < n-1:
temp[sushi[e]] += 1 # 새 초밥 추가
if temp[sushi[s]] == 1:
del temp[sushi[s]] # 초밥 개수가 0이면 삭제
else:
temp[sushi[s]] -= 1
e += 1
s += 1
max_cnt = max(max_cnt, len(temp) + (1 if c not in temp else 0))
print(max_cnt)
코드 설명
- 초기 설정
sushi.extend(sushi[:k-1])
를 통해 원형 회전 초밥을 리스트로 구현한다.collections.Counter
를 이용해 첫 번째 윈도우 (k
개의 초밥)를 설정한다.max_cnt
를 쿠폰 초밥 여부를 고려하여 초기화한다.
- 슬라이딩 윈도우 이동
- 새로운 초밥
sushi[e]
을 추가하고, 가장 앞의 초밥sushi[s]
을 제거한다. - 초밥 개수가 0이 되면
del
을 사용하여 딕셔너리에서 제거한다. e
와s
를 한 칸씩 이동하며 반복한다.
- 새로운 초밥
- 최대값 갱신
- 현재
temp
의 길이(종류 개수)를 확인하고, 쿠폰 초밥이 포함되지 않았다면 추가하여 최대값을 업데이트한다.
- 현재
시간 복잡도 분석
- 슬라이딩 윈도우를 활용하여
O(n)
의 시간 복잡도로 해결 가능하다. Counter
를 사용하여 초밥 개수를 관리하는 작업도O(1)
로 빠르게 처리된다.
[프로그래밍 언어/파이썬(Python)] - [Python] 파이썬 Counter 객체 활용 방법 정리
[Python] 파이썬 Counter 객체 활용 방법 정리
Counter 객체아이템에 대한 개수를 계산해 딕셔너리로 리턴해주는 아주 유용한 객체이다.importCounter 객체는 Python의 collections 모듈에 포함된 해시 가능한 객체의 개수를 셀 때 유용한 클래스이다.특
ynslee627.tistory.com
4. 결과
이 문제는 슬라이딩 윈도우와 Counter
활용이 핵심이다. 원형 리스트를 구현하는 방식과 함께, 쿠폰 초밥을 고려하는 방법까지 익혀두면 유사한 문제를 효율적으로 해결할 수 있다.
728x90
반응형