슬라이딩 윈도우를 이용하여 푸는 문제이다.투 포인터와 알고리즘 자체는 거의 똑같다.이상한데서 엄청 애먹었다.
import java.util.*;
import java.io.*;
public class Main {
static int count;
static int[] original;
static int[] newArr;
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
char[] A = br.readLine().toCharArray();
original = new int[4];
newArr = new int[4];
count=0;
int answer = 0;
st = new StringTokenizer(br.readLine()," ");
for(int i=0;i<4;i++){
original[i]= Integer.parseInt(st.nextToken());
if(original[i]==0) count++;
}
for(int i=0;i<M;i++){
Add(A[i]);
}
if(count==4) answer++;
// 애먹은부분!!!
for(int i=M;i<N;i++){
int j = i-M;
Add(A[i]);
Remove(A[j]);
if(count==4) answer++;
}
// 애먹은부분!!!
bw.write(String.valueOf(answer));
bw.flush();
bw.close();
br.close();
}
private static void Remove(char c) {
switch(c){
case 'A':
if(newArr[0]==original[0]) count--;
newArr[0]--;
break;
case 'C':
if(newArr[1]==original[1]) count--;
newArr[1]--;
break;
case 'G':
if(newArr[2]==original[2]) count--;
newArr[2]--;
break;
case 'T':
if(newArr[3]==original[3]) count--;
newArr[3]--;
break;
}
}
private static void Add(char c) {
switch(c){
case 'A':
newArr[0]++;
if(newArr[0]==original[0]) count++;
break;
case 'C':
newArr[1]++;
if(newArr[1]==original[1]) count++;
break;
case 'G':
newArr[2]++;
if(newArr[2]==original[2]) count++;
break;
case 'T':
newArr[3]++;
if(newArr[3]==original[3]) count++;
break;
}
}
}
for(int i=M;i<N;i++){
int j = i-M;
요 코드가 잘 이해가 안 갔다.저렇게 하면 이미 검사한 첫번째 문자열을 또 한번 검사하는거 아닌가 싶었는데 하나 하나 써보니까 한칸 앞을 더하고 맨 뒤에거를 빼더라.arr[2]는 두번째 칸이 아닌 세번째 칸이라는걸 잊지 말자