• HDU-1238-Substrings(KMP, 暴力枚举)


    链接:

    https://vjudge.net/problem/HDU-1238

    题意:

    You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.

    思路:

    n个字符串的最长子串, 反着的也可以.
    枚举第一个的子串, 对剩下的挨个匹配.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    #include <assert.h>
    #include <iomanip>
    #include <iostream>
    #include <sstream>
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    const int MAXN = 200;
    const int MOD = 1e4+7;
    
    string ori[MAXN], rev[MAXN];
    int Next[MAXN];
    int n;
    
    void GetNext(string t)
    {
        int i = 0, k = -1;
        int len = t.length();
        Next[0] = -1;
        while (i < len-1)
        {
            if (k == -1 || t[i] == t[k])
            {
                ++i;
                ++k;
                Next[i] = k;
            }
            else
                k = Next[k];
        }
    }
    
    
    bool Kmp(string s, string t)
    {
        int i = 0, j = 0;
        int lens = s.length(), lent = t.length();
        while (i < lens && j < lent)
        {
            if (j == -1 || s[i] == t[j])
            {
                ++i;
                ++j;
            }
            else
                j = Next[j];
        }
        return j >= lent;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
            cin >> n;
            for (int i = 1;i <= n;i++)
            {
                cin >> ori[i];
                rev[i].assign(ori[i].rbegin(), ori[i].rend());
            }
            int len = ori[1].length();
            int ans = 0;
            for (int i = 0;i < len;i++)
            {
                for (int j = i;j < len;j++)
                {
                    string p(ori[1], i, j-i+1);
                    GetNext(p);
                    bool flag = true;
                    for (int k = 2;k <= n;k++)
                    {
                        if (!Kmp(ori[k], p) && !Kmp(rev[k], p))
                        {
                            flag = false;
                            break;
                        }
                    }
                    if (flag && (int)p.length() > ans)
                        ans = (int)p.length();
                }
            }
            cout << ans << endl;
        }
    
        return 0;
    }
    
  • 相关阅读:
    [ZJOI2013]K大数查询 浅谈整体二分
    2019暑假杭二day1测试总结
    2019暑假杭二day2测试总结
    2019暑假杭二day3测试总结
    2019暑假杭二day4测试总结
    2019暑假杭二day5测试总结
    一些有趣的教学视频
    karatsuba乘法
    多项式求逆元
    FFT
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11594230.html
Copyright © 2020-2023  润新知