题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5510
题意:
给出n个字符串,求下标最大的字符串,存在下标小于它的字符串中有字符串不是他的子串。
题解:
首先能想到kmp+n^2暴力匹配,但是感觉会超时,因此我们需要加一些剪枝,水题,不要被他的数据范围吓到。。
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int T,n,m,vis[505];
int nex[505][2005];
char s[505][2005];
void getnex(int id)
{
int len=strlen(s[id]);
int j=-1;
for (int i=0;i<len;i++)
{
while(j!=-1 && s[id][i]!=s[id][j+1]) j=nex[id][j];
if (s[id][j+1]==s[id][i] && i!=0) j++;
nex[id][i]=j;
}
}
bool kmp(int ids,int idt)
{
int lens=strlen(s[ids]);
int lent=strlen(s[idt]);
int j=-1;
for (int i=0;i<lent;i++)
{
while(j!=-1 && s[ids][j+1]!=s[idt][i]) j=nex[ids][j];
if (s[ids][j+1]==s[idt][i]) j++;
if (j==lens-1)
return 1;
}
return 0;
}
int main()
{
int tot=0;
scanf("%d",&T);
while(T--)
{
tot++;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%s",s[i]);
for (int i=1;i<=n;i++)
{
vis[i]=0;
getnex(i);
}
int ans=-1;
for (int i=2;i<=n;i++)
{
for (int j=i-1;j>=1;j--)
{
if (vis[j]==1) continue;
if (kmp(j,i))
{
vis[j]=1;
// cout<<i<<‘ ‘<<j<<endl;
}
else
{
ans=i;
break;
}
}
}
printf("Case #%d: %d\n",tot,ans);
}
}
时间: 2024-10-12 11:54:02