Seek the Name, Seek the Fame
题目描述:
The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape
from such boring job, the innovative little cat works out an easy but fantastic algorithm:
Step1. Connect the father's name and the mother's name, to a new string S.
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S).
Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:)
Step1. Connect the father's name and the mother's name, to a new string S.
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S).
Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:)
The input contains a number of test cases. Each test case occupies a single line that contains the string S described above.
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.
ababcababababcabab aaaaa
2 4 9 18 1 2 3 4 5汉化:
小猫太有名了,许多夫妇都在山坡上爬坡到拜特兰,并要求小猫给新出生的婴儿命名。他们寻求名字,同时寻求名声。为了摆脱这种无聊的工作,创新的小猫制定了一个简单但奇妙的算法:
步骤1。将父亲的姓名和母亲的名字连接到一个新的字符串S.
第2步。找到一个合适的S前缀后缀字符串(不仅是前缀,也是S的后缀)。
例如:父亲='ala',母亲='la',我们有S ='ala'+'la'='alala'。 S的潜在前缀后缀字符串是{'a','ala','alala'}。给定字符串S,你能帮小猫编写一个程序来计算可能的前缀后缀字符串S的长度吗? (他可能会感谢你给宝宝一个名字:)
输入
输入包含一些测试用例。每个测试用例占用一个包含上述字符串S的行。
限制:输入中只能出现小写字母。 1 <= S <= 400000的长度。
产量
对于每个测试案例,按递增顺序输出带有整数的单行,表示新宝宝名字的可能长度。
示例输入
ababcababababcabab
AAAAA
示例输出
2 4 9 18
1 2 3 4 5
这次的心路历程顺手敲在了代码 里。想到哪敲到哪所以有点无厘头不过确实是思路。
///最暴力的方法就是开两个新的数组,分别从两个方向赋值,当a == b 时输出strlen(a)==
///可是如果要用这么暴力的方法那么KMP不就白学了嘛==
///所以要用KMP并且不那么暴力的方法
///是不是可以用KMP检测有没有一个后缀==前缀
///KMP的作用是检验重复字符串,那么就让初始字符串的长度不断增加,看能不能让正着的==后面倒数的
///也就是说KMP(f) ,输出的是第一段重复的首字符的位置,而
///我要找到最后一段重复的字符的末尾字符的位置是不是等于s的长度
///也就是说getkmp函数又又又不用动,把KMP函数和主函数改一改就行
///久违的EOF
///再再再次把GetNext搬过来
///可以把答案存在一个数组里,首先判断首项是否等于末项,if(s[0] == s[len - 1]) ans[0] = 1;
///上面这个思想不太OK,如果不写else那么变换不对称(个人理解),程序会出bug,所以那只是个特例
///不过答案当然是数组。数组的首项可以是一个一般结论。
///但是反过来可以让数组的首项ans[0]等于总长度,因为不管给的字符串是什么,总长度一定是一个解
///之后只要不断让长度变成next值,写一个循环直到next值为-1 也就是说倒着来
///输出这里要注意一下,之间用空格隔开而且最后换行,也就是说直到i减为零才换行
///输出的循环如果i = cnt那么会多出两个数据,所以先减掉2
///啊,终于做好了,先本地测试一下
///本地好像没问题
///WA了。日。
///忘记把测试改回来了。好了。AC代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int ne[400005];
int ans[400005];
char s[400005];
void GetNext(char *a)
{
int len = strlen(a);
int i = 0, j = -1;
ne[0] = -1;
while(i < len)
{
if(j == -1 || a[i] == a[j])
{
ne[++i] = ++j;
}
else j = ne[j];
}
}
int main()
{
while(scanf("%s", s) != EOF)
{
GetNext(s);
int lens = strlen(s);
int cnt = 0;
while(lens != -1)
{
ans[cnt++] = lens;
lens = ne[lens];
}
printf("%d*****\n", cnt);
for(int i = cnt - 2; i >= 0; i--)
{
if(i == 0)
printf("%d\n", ans[i]);
else
printf("%d ", ans[i]);
}
}
}