Period

题目描述:

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as A K , that is A concatenated K times, for some string A. Of course, we also want to know the period K.

输入:

The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.

输出:

For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

样例输入:

3
aaa
12
aabaabaabaab
0

样例输出:

Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4

code:

题意:
求字符串的最小周期
额,机翻的结果是这样的:

对于具有N个字符的给定字符串的每个前缀(每个字符的ASCII码在97126之间,包括),我们想知道该前缀是否是一个周期
字符串。即为每个我(2 < =< = N)我们想知道最大的K > 1(如果有的话),这样的前缀长度为我可以写成一个K,这是一个
连接K倍,对于一些字符串A。当然,我们也想知道K。

输入

输入文件由几个测试用例组成。每个测试用例由两行组成。第一行包含N (2 <= N <= 1 000 000)—字符串s的大小。第二
行包含字符串s。

输出

对于每个测试用例,在一行上输出“测试用例#”和连续的测试用例号;然后,对于每个长度为i,周期为K > 1的前缀,输出
前缀大小i和周期K之间用一个空格隔开;前缀大小必须按递增顺序排列。在每个测试用例之后打印一个空行。

思路:
求出所有前缀(满足是两个或两个以上的循环节组成的字符串)
输出前缀的位置[0-i-1]的i,以及循环节的个数
KMP求解fail数组,i-f[i]就是循环节长度

一开始数组开小了,,,结果告诉我超时????
改了很久才改对。。。。看来有时候不要太相信评测机给的反馈啊
又是一道KMP题,,,,

#include<stdio.h>
#include<string.h>
const int maxn=1e6+10;
char a[maxn];
int nextt[maxn]; 
int n;
void init()
{
	int i=0,j=-1;
	n=strlen(a);
	nextt[0]=-1;
	while(i<n)
	{
		if(j==-1||a[i]==a[j])
		{
			i++;
			j++;
			if((i%(i-j)==0)&&(i/(i-j)>1))
			{
				printf("%d %d\n",i,i/(i-j));
			}//这里是重点
			nextt[i]=j;
		}
		else j=nextt[j];
	}
}
int main()
{
	int n,kk=1;
	while(scanf("%d",&n)&&n)
	{
		scanf("%s",a);
		printf("Test case #%d\n",kk++);
		init();
		printf("\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值