Algorithm
[백준] 2531: 회전 초밥 JAVA
하다보면 되겠지
2023. 1. 15. 16:03
접근
이전 20922번과는 달리 k라는 일정한 간격이 정해져 있어서, 상대적으로 투포인터의 느낌이 옅은 것 같은 문제였다. 입력값 저장은 일차원 배열에 하지만 회전 초밥은 시작과 끝이 연결되어 있으므로 left (시작 지점)이 n-1번째까지 오도록 반복하고, right는 n과 같아질 경우 다시 0번째 인덱스로 돌려줬다. 나는 코드에서 d값을 쓰지는 않았다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 초기값 저장
int n = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int[] arr = new int[n];
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < n; i++)
arr[i] = Integer.parseInt(br.readLine());
// 처음 k개 초밥 계산
int cnt = 0;
for (int i = 0; i < k; i++) {
map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
if (map.get(arr[i]) == 1) cnt++;
}
int answer = cnt;
// 투포인터 적용
int right = k;
for (int left = 0; left < n; left++) {
if(right == n) right = 0;
map.put(arr[left], map.get(arr[left]) - 1);
if(map.get(arr[left]) == 0) cnt--;
map.put(arr[right], map.getOrDefault(arr[right], 0) + 1);
if(map.get(arr[right]) == 1) cnt++;
// 쿠폰 번호 확인
if(map.getOrDefault(c, 0) == 0) answer = Math.max(answer, cnt+1);
else answer = Math.max(answer, cnt);
// 포인터 이동
right++;
}
System.out.println(answer);
}
}