hdu5510Bazinga+KMP

来源:互联网 发布:js中使用java变量 编辑:程序博客网 时间:2024/06/05 17:58

For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤i≤n) 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 ofruizhang”, and rzhang" is not a substring ofruizhang”.

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

4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc

Sample Output

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

Source
2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

找出一个最大的i使得j属于0~i-1中,存在不是I的子串的。
解法:KMP直接找j是否是i的子串
优化:如果k是j的子串,那么下一次查找i时就没必要再查找k串了,

#include<bits/stdc++.h>using namespace std;char s[505][2002];void makeNext(const char P[],int next[]) {    int m = strlen(P);    next[0] = 0;    for (int q=1,k=0;q<m;++q) {        while(k>0&&P[q]!=P[k])  k=next[k-1];        if (P[q]==P[k]) k++;        next[q]=k;    }}int kmp(const char T[],const char P[],int next[]) {    int n = strlen(T);    int m = strlen(P);    makeNext(P,next);    for (int i=0,q=0;i<n;++i) {        while(q>0&&P[q]!=T[i]) q = next[q-1];        if (P[q]==T[i]) q++;        if (q == m){             q=next[q];             return (i-m+1); //匹配开始的位置        }    }    return -1; //不匹配}int main() {    int t;    scanf("%d",&t);    for(int cas=1; cas<=t; cas++) {        int n;        scanf("%d",&n);        for(int i=1; i<=n; i++) scanf("%s",s[i]);        int ans=0;        bool visit[555];        int next[2002];        memset(visit,0,sizeof(visit));        for(int i=1; i<=n; i++) {            for(int j=0; j<i; j++) {                if(visit[j]==true) continue;                if(kmp(s[i],s[j],next)==-1) ans=i;                else  visit[j]=true;            }        }        if(ans) printf("Case #%d: %d\n",cas,ans);        else printf("Case #%d: -1\n",cas);    }    return 0;}
0 0
原创粉丝点击