[문제링크]

 

15961번: 회전 초밥

첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 3,000,000, 2 ≤ d ≤ 3,000, 2

www.acmicpc.net

 

0. 슬라이딩 윈도우로, 다음 초밥을 넣고, 첫 초밥은 빼가며 종류를 센다 (큐 사용)

  - 회전초밥벨트이므로, 시작한 K개의 초밥이 마지막 초밥에 이어진다 

  - [시작부분] - [나머지] - [시작부분] 의 순서로 저장해서 처리

 

1. end포인터를 1씩 늘려가며 k개의 초밥을 받고, 종류를 센다

 

2. end포인터가 N+k가 될 때까지, end포인터의 초밥을 포함시키고, fst포인터의 초밥을 내보내는것을 반복한다

 

3. 위 과정중 구해진 가장 큰 cnt를 출력

 

개선점 : 모든 입력을 받고 시작하게 되면, 초밥을 큐로 관리할 필요가 없다

  - 큐 대신 포인터변수 2개만 사용해도 된다.

  - 반영함

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args)throws Exception {
		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());
		
		//d+1개의 배열 생성.
		int[] count = new int[d+1];
		count[Integer.parseInt(st.nextToken())]=1;//쿠폰은 항상 먹는다
		
		//초밥 종류 cnt변수
		int cnt=1, max=0;
		
		//처음 K개 저장할 배열 생성
		int[] saveFst = new int[N+k];
		for (int i = 0; i < N; i++) {
			saveFst[i]=Integer.parseInt(br.readLine());;
			if(i<k)saveFst[N+i]=saveFst[i];
		}
		
		int fst=0, end=0;
		for (; end < k; end++) {
			if(++count[saveFst[end]]==1)cnt++;
		}
		max=cnt;
		for (; end < N+k; end++) {
			if(++count[saveFst[end]]==1)cnt++;
			
			if(--count[saveFst[fst++]]==0)cnt--;
			
			if(max<cnt)max=cnt;
		}
		System.out.println(max);
		
	}
}

결과 화면

'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글

[백준] 4056 - 스-스-스도쿠  (0) 2021.04.16
[백준] 2239 - 스도쿠  (0) 2021.04.16
[백준] 2096 - 내려가기  (0) 2021.04.16
[백준] 2638 - 치즈  (0) 2021.04.15
[백준] 15686 - 치킨 배달  (0) 2021.04.15
[백준] 9935 - 문자열 폭발  (0) 2021.04.14
[백준] 1019 - 책 페이지  (0) 2021.04.13

+ Recent posts