1. 💎 문제
22862번: 가장 긴 짝수 연속한 부분 수열 (large)
수열 $S$에서 최대 $K$번 원소를 삭제한 수열에서 짝수로 이루어져 있는 연속한 부분 수열 중 가장 긴 길이를 출력한다.
www.acmicpc.net
2. 🤔 어떻게 풀까
무조건 삭제를 해야하므로(자세히 보면 삭제는 선택 사항이었음,,,) 무엇을 삭제할지 생각했을 때 홀수를 우선적으로 삭제해야 한다. 짝수 사이에 있는 홀수를 뺴줘야 이어질 수 있기 때문이다. 그리고 범위안에는 오직 최대 k개의 홀수만 있어야 하므로 홀수가 k개가 넘어가는 시점에서 걸러주는 작업을 하기로 했다.
그러므로 짝수와 홀수의 경우로 나눠 풀자고 생각했고, 투 포인터를 적용하여 `end`로는 수를 더하거나 탐색하고 `start`로는 수를 빼준다.
3. 💡 로직
1. 수열 입력
수열을 `nums`배열에 입력 받는다.
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int [] nums = new int[N+1];
st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++){
nums[i] = Integer.parseInt(st.nextToken());
}
2. 최단 짝수 수열 길이 구하기
수열에 차례대로 접근하여 홀수와 짝수를 판단한다. 짝수이면 수열의 길이를 더하록 고 홀수이면 홀수의 개수를 더한다. 만약 홀수의 개수가 k개를 넘어갔다면 수열의 범위를 수정 한다.
int start =0; int end = 0;
int length = 0; int odd_count =0;
// 홀수이면 k++, 짝수이면 count++,
while(end < N){
if(nums[end] %2 ==0){
length++;
}
else{
odd_count++;
}
end++;
result = Math.max(result, length);
if(odd_count <= K)
continue;
}
수정은 `start` 인덱스가 루프를 돌다 처음 홀수를 만날 떄 중단하며, 루프를 돌다 짝수를 만나면 짝수의 수만큼 수열의 길이에서 뺀다. 이때 수열의 길이을 감소하는 상황이 생기기 때문에 수정 작업 전에 결과를 저장한다.
{
result = Math.max(result, length);
while(true){
if(nums[start] %2 != 0){
odd_count--;
start++;
break;
}
else{ // 짝수
start++;
length--;
}
}
}
4. 📄 전체 코드
import java.io.*;
import java.util.StringTokenizer;
public class BOJ_가장긴짝수연속한부분수열 {
static BufferedReader br;
static BufferedWriter bw;
public static void main(String [] args) throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int [] nums = new int[N+1];
st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++){
nums[i] = Integer.parseInt(st.nextToken());
}
int start =0; int end = 0;
int length = 0; int odd_count =0;
int result = 0;
// 홀수이면 k++, 짝수이면 count++,
while(end < N){
if(nums[end] %2 ==0){
length++;
}
else{
odd_count++;
}
end++;
result = Math.max(result, length);
if(odd_count <= K)
continue;
// 초과 -가장 처음 만나는 홀수 제외
while(true){
if(nums[start] %2 != 0){
odd_count--;
start++;
break;
}
else{ // 짝수
start++;
length--;
}
}
}
System.out.println(result);
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[D2] 파스칼의 삼각형 (0) | 2023.11.09 |
---|---|
[G5] 숨바꼭질 3 : 13549 : Java - BFS (0) | 2023.11.06 |
[G4] 인구이동 : 16234 : Java - BFS, 구현 (1) | 2023.11.04 |
[S1] 쉬운 최단거리 : 14940 : Java - BFS (1) | 2023.11.04 |
[S1] 봄버맨 : Java : 16918 - BFS (1) | 2023.11.04 |