POJ 2752 Seek the Name, Seek the Fame

http://poj.org/problem?id=2752
这道题目的大意是:给你一个字符串,求他的前缀和后缀相等时的长度例如 字符串alala   :有 a=a ala=ala  alala=alala三种情况。答案是1 3 5  
解题思路KMP的next数组。 就如题目中的例子原串=ababcababababcabab,next=0 1 1 2 3 1 2 3 4 5 4 5 4 5 6 7 8 9 10

我们知道next[19]=10,意思也就是说你当前的字符串与原串在第19个字符不同了,你下一次跳到你要比较的字符串的第10和原串的第19位进行比较,根据next数组的定义,也就是说前缀的9个字符和后缀的9个是一样的所以直接让你的串的第10个和原串的19位相比较而next[10]=5,也就是说你已经比较完了前四个,直接第五个和19位比较,下面的一致类推.....

当然,实际的时候我们访问数组一般默认是从下标0开始到下标strlen(s)-1的,所以会有点差别。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 10000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
#define INF 1<<30
const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
char s[400003];
int m;
int f[400003];
void getFail(char *p,int *f)
{

m=strlen(p);
f[0]=0;
f[1]=0;
for(int i=1;i<m;i++)
{
int j=f[i];
while(p[i]!=p[j]&&j)
{
j=f[j];
}
f[i+1]=p[i]==p[j]?j+1:0;
}
// for(int i=1;i<=5;i++)
// cout<<f[i]<<"/"<<endl;
}
///要理解好f[]数组。
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int ans[400000];
while(~scanf("%s",&s))
{
getFail(s,f);
int num=0;
int j=m;
while(j!=0)///精辟经典经典
{
ans[++num]=j;
j=f[j];
}
for(int i=num;i>=1;i--)
{
cout<<ans[i];
if(i!=1)cout<<" ";
else cout<<endl;
}
}
return 0;
}


poj2752 Seek the Name, Seek the Fame - 风未定 - Guanjun的博客~~
 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值