zoukankan      html  css  js  c++  java
  • HDU 5510(KMP+思维)

    传送门

    题面:

    Bazinga

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 6560    Accepted Submission(s): 2003

     

    Problem Description

    Ladies and gentlemen, please sit up straight.
    Don't tilt your head. I'm serious.


    For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤in) such that there exists an integer j (1≤j<i) and Sj is not a substring of Si.

    A substring of a string Si is another string that occurs in Si. For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".

    Input

    The first line contains an integer t (1≤t≤50) which is the number of test cases.
    For each test case, the first line is the positive integer n (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn.
    All strings are given in lower-case letters and strings are no longer than 2000 letters.

    Output

    For each test case, output the largest label you get. If it does not exist, output −1.

    Sample Input

    
     

    45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc

    Sample Output

    
     

    Case #1: 4Case #2: -1Case #3: 4Case #4: 3

        

        题目描述:每次给你n个字符串S,问你最大的i,使得字符串Sj(0<=j<i)全都不是Si的字串。

        题面分析:通过读题,因为要求某个串是否是某个串的字串,因此可以判断出这是一道很经典的字符串匹配问题。

        从题目来看,这貌似就是一道很普通的多模匹配的问题,用AC自动机去解决,但是这题如果用AC自动机去做,先建树再用每一个字符串进行匹配的话会导致TLE。因此AC自动机在这个题目上并不适合。

        因此我们得拓宽我们的思维。

        进一步分析我们可以发现,对于第j串字符串,倘若前j串都是j的字串,那么我们下一步只需要判断j是否是j+1的字串即可(因为如果j是j+1的字串,而前j串又是j的字串,易得j+1串也是前j串的字串,进而得出前j+1串是j+1串的字串。)

        而倘若j串并不是j+1串的字串,那么下一步只需判断j串是否是j+2串的字串即可。

        因此,这道题就被巧妙地转化成了单模匹配的问题了。如此我们就可以通过KMP算法,使用类似指针的做法去用较短的时间匹配出答案。

        附上KMP算法的代码:

    #include <bits/stdc++.h>
    #define maxn 1005
    using namespace std;
    namespace CHENJR{//此处运用了命名保护,防止next数组报错
    
    int next[maxn];
    string str[maxn];
    void get_next(string s){
        memset(next,0,sizeof(next));
        int len=s.length();
        int i,j;
        j=next[0]=-1;
        i=0;
        while(i<len){
            while(j!=-1&&s[i]!=s[j]) j=next[j];
            next[++i]=++j;
        }
    }
    bool kmp(string a,string b){
        int lena=a.length();
        int lenb=b.length();
        get_next(b);
        int i=0,j=0;
        while(i<lena){
            while(j!=-1&&a[i]!=b[j]) j=next[j];
            i++,j++;
            if(j>=lenb) return true;
        }
        return false;
    }
    
    void main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int t;
        cin>>t;
        int cnt=0;
        while(t--){
            int n;
            cin>>n;
            for(int i=1;i<=n;i++){
                cin>>str[i];
            }
            int j=1;
            
            int ans=-1;
            for(int i=2;i<=n;i++){
                while(j<i&&kmp(str[i],str[j])){
                    j++;
                }
                if(j<i) ans=i;
            }
            cout<<"Case #"<<++cnt<<": "<<ans<<endl;
        }
    }
    
    }
    int main()
    {
        CHENJR::main();
        exit(0);
    }

        然而事实上,在头文件string.h内是含有一个strstr()函数用来寻找字串的。(但是需要注意的是,strstr()这个函数在最坏的情况下O(n^2)的复杂度,而kmp算法的复杂度是稳定在O(n)的。因此使用strstr()函数有风险,但是很省力省时间)对于这题,用strstr()函数是没有任何问题的。对于这个函数就当小小的积累了吧。

        附上代码:

    #include <bits/stdc++.h>
    #define maxn 2005
    using namespace std;
    char str[maxn][maxn];
    int main()
    {
        int t;
        int cnt=0;
        scanf("%d",&t);
        while(t--){
            memset(str,0,sizeof(str));
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%s",str[i]);
            }
            int ans=-1,j=1;
            for(int i=2;i<=n;i++){
                while(j<i&&strstr(str[i],str[j])){
                    j++;
                }
                if(j<i) ans=i;
            }
            printf("Case #%d: %d
    ",++cnt,ans);
        }
        return 0;
    }
  • 相关阅读:
    this,static,执行程序的顺序等等留意点
    PHP 中的 $this, static , self ,parent 等等关键字的总结
    css的继承之width属性(容易忽略)
    SDK和API之间有什么关系呢?
    JDK8下载账号分享
    Google大数据三篇著名论文-中文版
    HBase性能优化方法总结
    Hbase原理解析
    Java多线程
    XMind 是一个全功能的思维导图和头脑风暴软件,为激发灵感和创意而生
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007300.html
Copyright © 2011-2022 走看看