这又是什么神题啊。
这题一眼AC机。然后呢企鹅也是这么想的。
写完发现企鹅看错题了。然后其实建字典树就行了。
弄个v数组表示能否匹配到第i个位置。然后因为字典里的串很短,就判一下前面L(表示字典里最长那个串的长度)个位置能否匹配,可以的话就把那个位置后一位到当前位置抠出来,去字典树找有没有。
复杂度应该是O(m*len*L*L)蛮大的。
其实没这么可怕,因为不是每个位置都可以匹配到,然后匹配到一个OK就可以break了,还有,只要连续L个不能匹配,答案就出来了。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std;char ss[1100000]; struct Trie {int c,w[30];Trie(){c=0;memset(w,0,sizeof(w));} }tr[310];int trlen; void maketree() {int now=0,len=strlen(ss+1);for(int i=1;i<=len;i++){int x=ss[i]-'a'+1;if(tr[now].w[x]==0)tr[now].w[x]=++trlen;now=tr[now].w[x];}tr[now].c=1; } bool findchuan(int l,int r) {int now=0;for(int i=l;i<=r;i++){int x=ss[i]-'a'+1;if(tr[now].w[x]==0)return false;now=tr[now].w[x];}if(tr[now].c==0)return false;return true; }bool v[1100000]; int main() {int n,m,L=0;scanf("%d%d",&n,&m);trlen=0;for(int i=1;i<=n;i++){scanf("%s",ss+1);maketree();int len=strlen(ss+1);L=max(L,len);}while(m--){scanf("%s",ss+1);int len=strlen(ss+1);memset(v,false,sizeof(v));int ans=0;for(int i=1;i<=len;i++){bool bk=false;if(i<=L){bk=true;v[i]=findchuan(1,i);if(v[i]==true)ans=i;}if(v[i]==true)continue;for(int j=max(1,i-L);j<i;j++){if(v[j]==true){bk=true;v[i]=findchuan(j+1,i);if(v[i]==true){ans=i;break;}}}if(bk==false)break;}printf("%d\n",ans);}return 0; }