백준 12891번 (슬라이딩 윈도우)

김경욱·2025년 10월 13일

백준

목록 보기
100/121

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배열도 중요한 것 같다.

0개의 댓글