给你一堆字符串,编号从1到n,要求输出它上面所有字符串不全是它子串的最大位置,如果没有输出-1
主要就是KMP,每次在上面找到一个不匹配的子串就把位置记录下来,匹配时只匹配记录位置的子串和它前一个子串,如果记录位置的子串再后来被匹配成功了就消除这个位置。
样例
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
bc
ccc
输出
Case #1: 4
Case #2: -1
Case #3: 4
Case #4:3
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; int _next[2100]; char s[505][2100]; int lena,lenb; int num[505],l; void getnext(int tt) { int i=0,j=-1; _next[0]=-1; while(i<lenb) { if(j==-1||s[tt][i]==s[tt][j]) _next[++i]=++j; else j=_next[j]; } } int main() { int T; scanf("%d",&T); for(int k=1;k<=T;k++) { int n; scanf("%d",&n); int ok=-1;//ok means the final answer bool flag=false;//判断是否输出-1 l=0;//l代表不匹配的字符串数 for(int i=0;i<n;i++) { scanf("%s",s[i]); num[l+1]=i-1;//num储存不匹配的字符串的位置,num[]==-1时代表原来不匹配的在后来可以匹配了 if(i>1) for(int ka=1;ka<=l+1;ka++)//不知道为什么当时写的KMP函数一直调用不了,遂直接写到主函数里 { int j=num[ka]; if(j==-1) continue; memset(_next,0,sizeof(_next)); lena=strlen(s[i]); lenb=strlen(s[j]); int ans; int tb=j,ta=i; int ti=0,tj=0; getnext(tb); while(ti<lena&&tj<lenb) { if(tj==-1||s[ta][ti]==s[tb][tj]) { ti++; tj++; } else tj=_next[tj]; } if(tj<lenb&&ti==lena) { ans=-1; flag=true;//有一个不匹配就不会输出-1 num[++l]=i-1; ok=i+1; break; } else { ans=1; num[ka]=-1; } } } printf("Case #%d: ",k); if(flag==false) printf("-1\n"); else printf("%d\n",ok); } }