import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.util.*;
public class Main {
static int myArr[];
static int checkArr[];
static int checkSecret;
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 M = Integer.parseInt(st.nextToken());
int result = 0;
checkArr = new int[4];
myArr = new int[4];
String line = br.readLine();
char[] alpha = new char[N];
for (int i = 0; i < N; i++) {
alpha[i] = line.charAt(i);
}
StringTokenizer st2 = new StringTokenizer(br.readLine());
for (int i = 0; i < 4; i++) {
checkArr[i] = Integer.parseInt(st2.nextToken());
if (checkArr[i] == 0) {
checkSecret++;
}
}
for (int i = 0; i < M; i++) { // 부분 문자열 처음 받을때 세팅
Add(alpha[i]);
}
if (checkSecret == 4) result++;
// 슬라이드 윈도우
for (int i = M; i < N; i++) {
int j = i - M;
Add(alpha[i]);
Remove(alpha[j]);
if (checkSecret == 4) result++;
}
System.out.println(result);
}
private static void Add(char c) {
switch (c) {
case 'A':
myArr[0]++;
if (myArr[0] == checkArr[0]) checkSecret++;
break;
case 'C':
myArr[1]++;
if (myArr[1] == checkArr[1]) checkSecret++;
break;
case 'G':
myArr[2]++;
if (myArr[2] == checkArr[2]) checkSecret++;
break;
case 'T':
myArr[3]++;
if (myArr[3] == checkArr[3]) checkSecret++;
break;
}
}
private static void Remove(char c) {
switch (c) {
case 'A':
if (myArr[0] == checkArr[0]) checkSecret--;
myArr[0]--;
break;
case 'C':
if (myArr[1] == checkArr[1]) checkSecret--;
myArr[1]--;
break;
case 'G':
if (myArr[2] == checkArr[2]) checkSecret--;
myArr[2]--;
break;
case 'T':
if (myArr[3] == checkArr[3]) checkSecret--;
myArr[3]--;
break;
}
}
}
코테 강의를 들으면서 풀었다. 맨 처음에는 브루트포스방식으로 풀어 답은 나오지만 시간 초과가 발생하는 상황이 생겼다. 그 후 강의를 들은 후에는 슬라이딩 윈도우 방식으로 구간을 정한 후 하나씩 옆으로 갈때 그 구간에 있는 것을 전부 다 다시 검사하는 것이 아닌 들어오는 것 1개, 나가는 것 1개 이런 식으로 총 2가지만 검사하는 방식으로 문제를 풀었다. 메서드도 만들어야 해서 어려운 문제인 것 같다. 하지만 강의를 들으면서 풀으니까 이해는 훨씬 잘되고 기억에 잘 남는 것 같다. CheckSecret 변수가 이 문제에서 킥인 것 같다. 또한 myArr,checkArr배열도 중요한 것 같다.