3508. 最長共通部分文字列

Powered by: NEFU AB-IN

リンク

3508. 最長共通部分文字列

  • タイトルの意味

    2 つの文字列が与えられた場合、数字を含まない 2 つの文字列の最も長い共通部分文字列の長さを見つけます。

  • 一連の考え

    まず、dpメソッドを使用して激しく行うことができ、複雑さはO(n 2)O(n ^ 2)ですO ( n2 )別の文字列
    をスキャンするときに最後に数字がないかどうかを判断します。 1つは、各文字列の数字を異なる記号に置き換えることができます

  • コード

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #undef int
    
    #define ULL unsigned long long
    
    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define IOS                                                                                                            \
        ios::sync_with_stdio(false);                                                                                       \
        cin.tie(nullptr);                                                                                                  \
        cout.tie(nullptr)
    #define DEBUG(X) cout << #X << ": " << X << '\n'
    typedef pair<int, int> PII;
    
    const int N = 1e5 + 10, INF = 0x3f3f3f3f, P = 13331;
    ULL hs[N], ps[N], ht[N], pt[N];
    string s, t;
    
    ULL gets(int l, int r)
    {
          
          
        return hs[r] - hs[l - 1] * ps[r - l + 1];
    }
    ULL gett(int l, int r)
    {
          
          
        return ht[r] - ht[l - 1] * pt[r - l + 1];
    }
    
    bool check(int x)
    {
          
          
        unordered_set <int> us;
        for(int i = 1; i + x - 1 < SZ(s); ++ i){
          
          
            us.insert(gets(i, i + x - 1));
        }
        for(int i = 1; i + x - 1 < SZ(t); ++ i){
          
          
            if(us.count(gett(i, i + x - 1))) return true;
        }
        return false;
    }
    
    signed main()
    {
          
          
        IOS;
    
        cin >> s >> t;
    
        s = " " + s;
        t = " " + t;
    
        for(int i = 1; i < SZ(s); ++ i){
          
          
            if(s[i] >= '0' && s[i] <= '9') s[i] = '#';
        }
    
        for(int i = 1; i < SZ(t); ++ i){
          
          
            if(t[i] >= '0' && t[i] <= '9') t[i] = '$';
        }
    
        ps[0] = pt[0] = 1;
        for(int i = 1; i < SZ(s); ++ i){
          
          
            ps[i] = ps[i - 1] * P;
            hs[i] = hs[i - 1] * P + s[i];
        }
    
        for(int i = 1; i < SZ(t); ++ i){
          
          
            pt[i] = pt[i - 1] * P;
            ht[i] = ht[i - 1] * P + t[i];
        }
    
        int l = 0, r = min(SZ(s), SZ(t));
        while(l < r){
          
          
            int mid = l + r + 1 >> 1;
            if(check(mid)) l = mid;
            else r = mid - 1;
        }
        cout << r;
        return 0;
    }
    

おすすめ

転載: blog.csdn.net/qq_45859188/article/details/130272387