HDU - 5510——(KMP)

總結

這個題,自己沒算好時間複雜度TLE了好幾次,最後發現暴力+KMP時間複雜度是O(t * n2 * 2m)早就超1e8了,這裏肯定得優化,你會發現,就算O(1)算法判斷子串,也是2.5e6,已經很大了。中間肯定得優化,你會發現,有的地方可以不用計算的,
情況1:如果j是i的子串,那麼以後比i更大的str只需要訪問i,j也就不用計算,因爲如果i是它的子串,那麼j一定是它的子串,
情況2:如果j不是i的字符串,那麼就提前跳出來。保證每次t只計算n次kmp。

註釋:如果不提前跳出來,測試案例,所有字符串都不存在兩兩子串的關係,那麼就會TLE,當然我個人認爲hdu的測試案例不夠強。

時間複雜度

t=50
n=500
m=2e3
O(t*(n2+n*2m))== 1.25e7+1e8
不知道是自己分析有問題,還是數據太弱,感覺這個複雜度過很勉強

題意:求最大的i,且存在j不是i的子串(j<i),否則爲-1

題目鏈接

//#pragma GCC optimize(2)
#include<bits/stdc++.h>
//typedef long long ll;
#define ull       unsigned long long
#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<<flush
#define eps         1e-6
#define base        131
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define pa          pair<int,int>
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
    //  freopen("D:/LSNU/codeforces/duipai/cout.txt","w",stdout);
#endif
}
const int N=1e3+5;
bool vis[N];
struct Kmp
{
    vector<int>Next;///Next數組統計的是最大的前綴與後綴相同長度
    Kmp(string &p){
        int len=p.size();
        int k=-1,j=0;
        Next.pb(-1);
        while(j<len-1){
            if(k==-1||p[k]==p[j]){
                k++,j++;
                Next.pb(k);
            }
            else{
                k=Next[k];
            }
        }
    }
    int search(string &s,string &p){
        int i=0,j=0,cnt=0;
        int lens=s.size(),lenp=p.size();
        while(i<lens&&j<lenp){
            if(j==-1||s[i]==p[j])
                i++,j++;
            else
                j=Next[j];
        }
        if(j==lenp)
            return i-j+1;
        return 0;
    }
};
void solve()
{
    int n;
    cin>>n;
    string str[n];
    for(int i=0;i<n;i++)
        cin>>str[i];
    memset(vis,0);
    int ans=-1;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<i;j++)
        {
            if(vis[j])
                continue;
            Kmp temp(str[j]);
            if(temp.search(str[i],str[j])==0)
            {
                ans=i+1;
                break;
            }
            else
                vis[j]=true;
        }
    }
    cout<<ans<<endl;
}
signed main()
{
    IOS;
    // file();
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        cout<<"Case #"<<i<<": ";
        solve();
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章