题目:
http://acm.hdu.edu.cn/showproblem.php?pid=4763题意:
一首歌有一个主题部分,就是在开头,结尾和中间都出现的一段歌词,现在给出k首歌的歌词,找出每首歌的主题部分长度。思路:
就是求最长子段是前缀,后缀和中间出现,并且不重叠。
既是前缀又是后缀,那就明显是kmp的next数组可以直接求得,next[len]的值就是了。
再就是要找该部分在中间出现过,直接扫一遍中间是否出现过next[len],
保证互相覆盖就是只扫2*next[len]到len-next[len]的部分。
另外可能出现结果不是最长前后缀的情况,就是搜索失败的时候找next[next[len]],也就是最长前后缀中也是前后缀的长度。
枚举找下去就是了。主要是熟悉kmp。
代码:
#define N 1123456
int n,m;
int flag,sum,ave,ans,res,len,ans1,ans2;
int a[N];
char s[N];
void getnext(char *pre, int len, int *next)
{
int i = 0,j = -1;
next[0] = -1;
while(i < len)
{
if(j == -1 || pre[i] == pre[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
}
int main()
{
int i,j,k,kk,t,x,y,z;
scanf("%d",&k);
while(k--)
{
scanf("%s",s);
m = n = strlen(s);
getnext(s,n,a);
flag = 1;
while(n>0 && flag)
{
res=a[n];
for(i=2*res;flag && i<=m-res;i++)
if(a[i]==res)
flag = 0;
n=a[n];
}
printf("%d\n",res);
}
return 0;
}