D - Power Strings POJ - 2406

D - Power Strings POJ - 2406

Given two strings a and b we define ab to be their concatenation. For example, if a = “abc” and b = “def” then ab = “abcdef”. If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = “” (the empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
abcd
aaaa
ababab
.
Sample Output
1
4
3
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.

  • 题意:定义一个算法,对于字符串a,an表示有n个a相连接。然后给你一个字符串s,找出一个尽可能大的n,能够满足an=s

  • 解题思路:这个题我们可以用kmp的方法进行求解,具体的kmp请参考这篇博客 kmp详解

    这里讲解一下用kmp的原理,kmp的原理首先是对字符串进行一个预处理一个next数组,这个数组表示的内容为如果当前位置i这个字符不匹配的话,那么直接匹配nex[i]的字符,因为i的前面和next[i]的前面是相同的。因此,我们对s进行预处理,如果只看最后一个位置的next[i]的值的话,那么字符串s的前next[i]长度的字符和后next[i]长度的字符是相同的。那么如果要是满足一个n>1的情况下的话,一定存在s.length()/(s.length()-nex[s.length()],的余数是一个为0,并且那个字符串a即为s从头开始长度为s.length()-nex[s.length()].
    证明:记c=s.length-nex[s.length()], len为字符串长;根据nex的原理我们可以知道s[0]=s[len-c-1],s[1]=s[len-c]…s[c]=s[len-1],所以a的长度便是c的值,我们假设如果存在a的长度大与c的话,那么为了满足上面一些式子成立,a长度为c的答案也是一定成立的,而且a长度越小n越大。如果a的长度小于c的话,那么根据nex数组形成的原理,我们已经可以保证nexs.[length()]的长度比现在的长。证毕

代码:

#include
#include
using namespace std;
const int inf = 1e6;
string s;
char sn[inf];
int p[inf];
int nex[inf];
void Getnex(){
	nex[0]=-1;
	int j=0,k=-1;
	while(j<s.size()){
		if(k==-1||s[k]==s[j]){
			j++;k++;
			nex[j]=k;
		}else k=nex[k];
	}
}
int main()
{	
	int cas=0;
	while(cin>>s){
		if(s==".")break;
		Getnex();
		int c=nex[s.size()];//cout<
		//cout<
		if(s.size()%(s.size()-c)==0){cout<<s.size()/(s.size()-c)<<endl;}
		else cout<<"1"<<endl;
	}
	return 0;
}
posted @ 2018-10-19 15:47 i-Curve 阅读( ...) 评论( ...) 编辑 收藏

你可能感兴趣的:(D - Power Strings POJ - 2406)