ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ 20437 - 문자열 게임2
    PS 2024. 7. 31. 09:26

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

     

    생각한대로 풀려서 기분이 너무 좋았다. 

    findLongestSubArray문제를 풀어봤던 것이 도움이  됐다.

     

    알파벳이 몇개 나왔나 카운트 하는 배열이 있고,

    어떤 글자가 어떤 인덱스에 나왔다 저장하는 벡터 배열을 만든다.

    vector<int> loc[30]; // 어떤 글자가 나온 인덱스들을 저장    ex) a가 2, 5, 8번 인덱스에 나왔다면 loc[0] = {2,5,8};

     

    그리고 글자수를 돌아가며 카운트를 세고, loc에 각각 나온 인덱스를 저장해준다.

    그러다가 카운트가 k개 이상이 나오면, 현재 인덱스와 loc의 마지막에서 k개만큼 빼주면, k개 이전의 인덱스가 나온다.

    그럼 이제 현재 인덱스 - 이전에 같은 글자가 나왔던 인덱스 + 1을 해주면 된다. (+1을 해주는 이유는 현재인덱스와 이전인덱스를 둘다 포함해줘야 하기 때문이다.)

     

     

    처음에는 vector<int> loc[30]이 아니라 int strt[30] 이라는 배열을 만들고 -1로 채운 후, 처음 해당알파벳이 나오면 해당인덱스로 채워주고, k번째 카운트 이상이 나오면 그 인덱스에서 스타트부분을 빼주고 +1 하는 식으로 하려 했었다. 

    하지만 문제를 풀며 조금 생각해보니 반례가 생각났는데

    ex)

    1

    abaa

    2

    일때, 

    스타트만 저장하게 된다면 b다음의 a들이 스타트부분만 빼게되고, 그럼 최소값과 최대값 둘다 aba인 3만 나오게 될거라는 생각이 들었다.

    그래서 vector<int>[30]으로 고쳐주고, 마지막에서 k개를 뺀 만큼 앞으로 가면, k번 전에 해당하는 인덱스가 나오고,

    그걸 k번째인 현재 인덱스 - k번  전에 해당하는 인덱스 를 해주면 길이가 나올 것이라고 생각해볼 수 있었다.

     

    지금 생각해보니 cnt배열도 필요 없을것 같다. 그냥 loc[s[i]].size()로 글자가 몇개 나왔나 확인할 수 있다.

     

    #include <bits/stdc++.h>
    using namespace std;
    int t;
    string s;
    int k;
    
    int cnt[30]; // 알파벳 몇개나왔나 카운트
    int main()
    {
        cin >> t;
        while (t--)
        {
            int mn = 10001;
            int mx = 0;
            vector<int> loc[30]; // 어떤 글자가 나온 인덱스들을 저장    ex) a가 2, 5, 8번 인덱스에 나왔다면 loc[0] = {2,5,8};
    
            fill(cnt, cnt + 30, 0);
            cin >> s;
            cin >> k;
            for (int i = 0; i < s.size(); i++)
            {
                int charNum = s[i] - 'a';
                loc[charNum].push_back(i);
                cnt[charNum]++;
    
                if (cnt[charNum] >= k)
                {
                    // int len = i - (loc[charNum].size()-k)
                    int preIdx = loc[charNum].size() - k;
                    int pre = loc[charNum][preIdx];
                    int len = i - pre + 1;
                    mn = min(mn, len);
                    mx = max(mx, len);
                }
            }
    
            if (mn == 10001 && mx == 0)
            {
                cout << -1 << "\n";
            }
            else
            {
                cout << mn << " " << mx << "\n";
            }
        }
        return 0;
    }

    'PS' 카테고리의 다른 글

    6.유저인증 - JWT - 로그인, 회원가입등을 만들어보자. - 서버 ++ 에러핸들링  (1) 2024.08.01
    BOJ 14719 빗물  (0) 2024.08.01
    BOJ 15989 - 1, 2, 3 더하기 4  (0) 2024.07.30
    BOJ 12919 A와 B 2  (6) 2024.07.23
    7. Optimistic Update  (1) 2024.07.22

    댓글

Designed by Tistory.