ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1553-B, *1300
    코드포스 2021. 7. 28. 21:50
     

    Problem - 1553B - Codeforces

     

    codeforces.com

    문제

    • 문자열 $s(1 \leq \left | s \right | \leq 500)$와 $t(1 \leq \left | t \right | \leq 2 \cdot \left | s \right |-1)$가 주어진다
    • 스케너가 임의의 $s$ 문자 위에서 오른쪽으로 갔다가 왼쪽으로 차례로 읽을 때 $t$로 읽을 수 있는가?

     

    $O(t^{2}s)$

    먼저 스캔했을 때 $t$가 나올 수 있는 문자열을 구하자 --- !

    스케너가 오른쪽으로 갔다가 왼쪽으로 가기 시작하는 문자를 $key$라고 하자
    $t$의 각 자리별로 $key$라고 생각하고 ! 을 구한다 $O(t^2log\ t)$
    스케너는 항상 오른쪽을 먼저 가기 때문에 ! 의 제일 오른쪽에는 $key$가 위치한다 

    이제 ! 가 $s$에 포함되는지 찾는다 $O(t^2s)$

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <bits/stdc++.h>
    #define endl "\n"
    using namespace std;
     
    string s;
    string t;
     
    string flip(int end)
    {
        int l, r;
        l = r = end;
        while(l-1 >= 0 && r+1 < t.size() && t[l-1]== t[r+1]){
            l--;
            r++;
        }
     
        string res;
        if(l == 0){
            res = t.substr(end, t.size()+end-l);
            reverse(res.begin(), res.end());
            return res;
        }
        else if(r == t.size()-1){
            return t.substr(0end+1);
        }
        else return t;
    }
     
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
     
        int q;
        cin >> q;
        while(q--){
            cin >> s >> t;
            set<string> able;
            for(int right = 0; right < t.size(); right++){
                able.insert(flip(right));
            }
     
            bool flag = false;
            for(auto e: able) {
                if(s.find(e) != string::npos) {
                    flag = true;
                    break;
                }
            }
     
            cout << (flag? "YES""NO"<< endl;
     
        }
     
        return 0;

     

    $O(s^{3})$

    이번 풀이는 $s$에서 스케너가 길이 $\left | t \right |$만큼 스캔할 때 읽는 모든 경우를 따져본다

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <bits/stdc++.h>
    #define endl "\n"
    using namespace std;
     
    string s, t;
     
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
     
        int q;
        cin >> q;
        while(q--){
            bool able = false;
            cin >> s >> t;
            for(int i = 0; i < s.size(); i++){
                for(int j = 0; j < s.size()-i; j++){
                    int k = t.size() - j -1;
                    int l1 = i;
                    int r = i+j;
                    int l2 = r-k;
                    if(k < 0 || l2 < 0continue;
     
                    string part1 = s.substr(l1, j+1);
                    string part2 = s.substr(l2, k);
                    reverse(part2.begin(), part2.end());
     
                    if(part1 + part2 == t) able = true;
                }
            }
     
            cout << (able ? "YES""NO"<< endl;
     
        }
     
     
        return 0;

     

    두 풀이의 실제 수행시간 비교

    왼쪽부터 각각 $O(t^{2}s),\ O(s^{3})$이다

    '코드포스' 카테고리의 다른 글

    1555-C, *1300  (0) 2021.07.31
    1547-D, *1300  (0) 2021.07.30
    459-B, *1300  (0) 2021.07.28
    451-B, *1300  (0) 2021.07.28
    189-A, *1300  (0) 2021.07.27

    댓글

Designed by Tistory.