• HDU 5510 题解


    题意:对于n个字符串,找到最大的i,满足条件:S1,S2,……,Si-1中至少存在一个字符串不是Si的子串。

    1<=N<=500;字符串长度不超过2000.共1~50组数据,1000MS

    算法/思路:

    KMP即可,先从大到小判断KMP(Si,Si+1),若连续为真,说明Si为Si+1,Si+2,……,Sn的子串;若到某个i为假,说明Si+1满足条件(但未必最大)。注意此时Si+1为Si+2,……,Sn的子串,故Si+1的子串必定为Si+2,……,Sn的子串。

    令bound=i+1如果kmp(i,bound)不成立,那么bound满足条件,++bound,否则--i(因为当前Si是bound及以后字符串的子串,没有判断价值),继续进行判断,直到i=1或者bound=n+1,答案为bound-1,复杂度为O(n*length)。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int maxn=3000;
    
    char s[600][maxn];
    int next1[maxn][maxn];
    
    int t,n,ans,bound;
    
    void ms(int v){
        int n=strlen(s[v]);int i=0,j=-1;next1[v][0]=-1;
        while (i!=n){
            if (j!=-1 && s[v][i]!=s[v][j]) j=next1[v][j];
            ++i;++j;
            if (s[v][i]==s[v][j]) next1[v][i]=next1[v][j];else next1[v][i]=j;
        }
    }
    
    int kmp(int a,int b){
        int n=strlen(s[a]),m=strlen(s[b]);
        int i=0,j=0;
        while (i<m){
            if (s[b][i]==s[a][j]){
                ++i;++j;
                if (j==n) return (i-n+1);
            }    else if (next1[a][j]!=-1) j=next1[a][j];
                        else {j=0;++i;}
        }
        return -1;
    }
    
    int main(){
        cin>>t;
        for (int q=1;q<=t;++q){
            cin>>n;
            for (int i=1;i<=n;++i){
                scanf("%s",&s[i]);
                ms(i);
            }
            int i;
            //for (int i=1;i<=n;++i)
                //for (int j=i+1;j<=n;++j) cout<<kmp(i,j)<<endl;
            //cout<<kmp(3,4)<<"asd "<<endl;
            for (i=n-1;i>=1 && kmp(i,i+1)!=-1;--i);
            if (i==0) ans=-1;else{
                bound=i+1;
                for (;i>=1 && bound<=n;--i){
                    while (bound<=n && kmp(i,bound)==-1) ++bound;    
                }
                ans=bound-1;
            }
            printf("Case #%d: %d
    ",q,ans);
        }
        return 0;
    }
  • 相关阅读:
    powermock测试
    一些疑惑
    Java基础总结3
    Java学习路线
    Java基础总结2
    关于我
    翻转单词序列
    和为s的两个数字
    和为s的连续正数序列
    数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/terra/p/7008278.html
Copyright © 2020-2023  润新知