[백준] | JAVA, 자바 | 12891번 - DNA 비밀번호

https://www.acmicpc.net/problem/12891


문제 요약 :

1. DNA 문자열 길이 S, 비밀번호로 사용할 부분문자열의 길이 P 입력받기

2. 임의로 만든 DNA 문자열 입력받기

3. 부분 문자열에 포함되어야 할 최소 개수 입력받기

4. 민호가 만들 수 있는 비밀번호의 종류의 수를 구하는 프로그램을 작성


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

public class Main {
    private static int resultCnt, p;
    private static int[] useCnt, tryCnt;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();
        // 1. DNA 문자열 길이 S, 비밀번호로 사용할 부분문자열의 길이 P 입력받기
        int s = Integer.parseInt(st.nextToken());
        p = Integer.parseInt(st.nextToken());
        useCnt = new int[4];
        tryCnt = new int[4];
        resultCnt = 0;
        // 2. 임의로 만든 DNA 문자열 입력받기
        String dna = br.readLine();
        st = new StringTokenizer(br.readLine());
        // 3. 부분 문자열에 포함되어야 할 최소 개수 입력받기
        for (int i = 0; i < 4; i++) {
            useCnt[i] = Integer.parseInt(st.nextToken());
        }

        // 최초 p만큼 업데이트
        for (int i = 0; i < p; i++) {
            char c = dna.charAt(i);
            updatePassword(c, 1);
        }

        // 최초 상태 확인
        if (canMakePassword(tryCnt)) resultCnt++;

        // 슬라이딩윈도우 사용
        for (int i = 0; i < s - p; i++) {
            char before = dna.charAt(i);
            char after = dna.charAt(i + p);
            updatePassword(before, -1);
            updatePassword(after, 1);
            // 업데이트 된 상태 확인
            if (canMakePassword(tryCnt)) resultCnt++;
        }
        sb.append(resultCnt);
        // 4. 민호가 만들 수 있는 비밀번호의 종류의 수를 구하는 프로그램을 작성
        System.out.println(sb);
    }

    private static void updatePassword(char c, int add) {
        if (c == 'A') {
            tryCnt[0] += add;
        } else if (c == 'C') {
            tryCnt[1] += add;
        } else if (c == 'G') {
            tryCnt[2] += add;
        } else if (c == 'T') {
            tryCnt[3] += add;
        }
    }

    // 주어진 DNA 문자열에서 부분문자열에 포함되어야 할 최소 개수를 충족시키는지 확인
    private static boolean canMakePassword(int[] cntList) {
        for (int i = 0; i < 4; i++) {
            if (cntList[i] < useCnt[i]) {
                return false;
            }
        }
        return true;
    }
}