문제설명
https://www.acmicpc.net/problem/2531
2531번: 회전 초밥
첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 30,000, 2 ≤ d ≤ 3,000, 2 ≤
www.acmicpc.net
알고리즘
이번 문제는 단순하게 반복문으로 결과를 구해낼 수 있다
하지만 시간 제약이 있기 때문에 sliding window를 사용해야한다
k개를 확인해서 초밥의 갯수를 세기때문에 1칸씩 옮겨가며 연산한다
이때 모든 초밥을 다 다시세면 반드시 시간초과가 발생하기 때문에, 새로 추가되는 초밥만 세고 먹을 수 없는 초밥은 빼는 것이 문제의 해결 방식이다
아래의 코드는 시간초과가 발생했던 방식이다
import sys
def Input_Data():
read = sys.stdin.readline
N, d, k, c = map(int,read().split())
dish = [int(read()) for _ in range(N)]
return N, d, k, c, dish
def Check():
global visited
cnt =0
visited[c] += 1
for i in range (1,d+1):
if visited[i]>0:
cnt +=1
# print(visited)
visited = [0 for i in range(d+1)]
return cnt
def Solve():
arr = []
for i in range(0,N):
for j in range(i,i+k):
if j >= N:
j %= N
cur = dish[j]
visited[cur] += 1
# print(dish[i:i+k])
arr.append(Check())
return max(arr)
sol = 0
# 입력
N, d, k, c, dish = Input_Data()
visited = [0] * (d+1)
sol = Solve()
print(sol)
해당 방식으로 문제를 해결하니 시간초과가 발생했다
코드
import sys
def Input_Data():
read = sys.stdin.readline
N, d, k, c = map(int,read().split())
dish = [int(read()) for _ in range(N)]
return N, d, k, c, dish
def Check(cur_save): #sliding window를 한칸 옮겨 먹을 수 없는 초밥을 빼고 새로운 초밥 더하기
sushi[cur_save]-=1
cnt = len(sushi)
if sushi[cur_save] == 0:
del(sushi[cur_save])
return cnt
def Solve():
for i in range(k-1): #뒤로 이어질 초밥을 미리 저장 -> modulo로도 계산가능함
dish.append(dish[i])
sushi[c] = 1 #쿠폰을 사용 초밥 미리 체크
for i in range(0,k):
cur = dish[i]
if cur in sushi:
sushi[cur] +=1
else:#새로운 초밥인 경우
sushi[cur] =1
res = Check(dish[0])#먹을 수 있는 초밥 수 반환
if res == k+1:#최대 종류의 수를 먹을 수 있는 경우 연산 종료
return res
for j in range(k, len(dish)):#초밥 종류 계산 -> sliding window를 한 칸 옮겨 연산
cur = dish[j]
if cur in sushi:
sushi[cur] +=1
else:
sushi[cur] =1
res = Check(dish[j-k+1])#초밥 가짓 수 확인
arr.append(res)
return max(arr)
sol = 0
# 입력
N, d, k, c, dish = Input_Data()
sushi = {}
# 함수실행
sol = Solve()
print(sol)
고찰
이번 문제는 sliding window의 필요성을 확실하게 느낄 수 있는 문제였다
반복되는 연산은 스킵하고 옮겨가면서 새로운 값만 조회하면 되서 시간초과를 피할 수 있었다
바꾼 코드도 줄일 수 있겠지만 시간이 모잘라 스킵했다
'Algorithm' 카테고리의 다른 글
[백준 6236] 용돈 관리 (0) | 2024.01.31 |
---|---|
[백준 3055] 탈출 (1) | 2024.01.31 |
[백준 1920] 수 찾기 (0) | 2023.05.17 |
[프로그래머스] 추억 점수 (0) | 2023.05.12 |
[백준 2468] 안전 영역 (0) | 2023.04.11 |