알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][20437] 문자열 게임 2

kim.svadoz 2021. 5. 11. 22:27
반응형

www.acmicpc.net/problem/20437

 

20437번: 문자열 게임 2

첫 번째 문자열에서 3번에서 구한 문자열은 aqua, 4번에서 구한 문자열은 raquator이다. 두 번째 문자열에서는 어떤 문자가 5개 포함된 문자열을 찾을 수 없으므로 -1을 출력한다.

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 1024 MB 235 119 102 56.044%

문제

작년에 이어 새로운 문자열 게임이 있다. 게임의 진행 방식은 아래와 같다.

  1. 알파벳 소문자로 이루어진 문자열 W가 주어진다.
  2. 양의 정수 K가 주어진다.
  3. 어떤 문자를 정확히 K개를 포함하는 가장 짧은 연속 문자열의 길이를 구한다.
  4. 어떤 문자를 정확히 K개를 포함하고, 문자열의 첫 번째와 마지막 글자가 해당 문자로 같은 가장 긴 연속 문자열의 길이를 구한다.

위와 같은 방식으로 게임을 T회 진행한다.

입력

문자열 게임의 수 T가 주어진다. (1 ≤ T ≤ 100)

다음 줄부터 2개의 줄 동안 문자열 W와 정수 K가 주어진다. (1 ≤ K ≤ |W| ≤ 10,000)

출력

T개의 줄 동안 문자열 게임의 3번과 4번에서 구한 연속 문자열의 길이를 공백을 사이에 두고 출력한다.

만약 만족하는 연속 문자열이 없을 시 -1을 출력한다.

예제 입력 1

2
superaquatornado
2
abcdefghijklmnopqrstuvwxyz
5

예제 출력 1

4 8
-1

첫 번째 문자열에서 3번에서 구한 문자열은 aqua, 4번에서 구한 문자열은 raquator이다.

두 번째 문자열에서는 어떤 문자가 5개 포함된 문자열을 찾을 수 없으므로 -1을 출력한다.

예제 입력 2

1
abaaaba
3

예제 출력 2

3 4

코드

import java.util.*;
import java.io.*;

public class p20437 {
    static int t;
    static List<Integer>[] alpha;
    static LinkedList<Integer> list;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        t = Integer.parseInt(br.readLine());
        while (t-- > 0) {
            String str = br.readLine();
            int cnt = Integer.parseInt(br.readLine());

            int step3 = game(str, cnt, 3);
            sb.append(step3);
            if (step3 != -1) {
                int step4 = game(str, cnt, 4);
                sb.append(" ").append(step4);
            }
            sb.append("\n");
        }
        System.out.println(sb.toString());
    }

    static int game(String str, int cnt, int step) {
        // 각각 알파벳이 나온 자리의 인덱스를 저장하기 위한 리스트
        alpha = new ArrayList[26];
        for (int i = 0; i < 26; i++) {
            alpha[i] = new ArrayList<>();
        }

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            alpha[c - 'a'].add(i);
        }
        list = new LinkedList<>();

        for (int i =0; i < 26; i++) {
            int size = alpha[i].size();
            // 각각 알파벳이 나온 인덱스를 저장한 리스트의 길이가 목표 보다 작으면 넘어가고
            if (size < cnt) {
                continue;
            }

            // alpha[i] 번재 인덱스에 목표와 같은 문자가 나왔다.
            for (int idx = 0; idx < size - cnt + 1; idx++) {
                list.offerLast(alpha[i].get(idx + cnt -1) - alpha[i].get(idx) + 1);
            }
        }

        if (list.size() == 0) {
            return -1;
        }
        int min = 10001;
        int max = 0;

        while(!list.isEmpty()) {
            int val = list.poll();

            min = Math.min(min, val);
            max = Math.max(max, val);
        }

        return step == 3 ? min : max;
    }
}
반응형