POJ 2406 (自身字符串最大重复次数)
Power Strings
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 58639 Accepted: 24382
Description
Given two strings a and b we define a*b to be their concatenation. For example, if a = “abc” and b = “def” then a*b = “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.
题意:给定一个字符串,这个字符串是有一个字符串重复拼接n次而成的,找到最大的一个n
分析:使用nxt数组找到最长前后缀,那么只要剩下的字符串长度可以被原始字符串长度整余则结果为最大的n
AC code
#define _CRT_SBCURE_NO_DEPRECATE
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define maxn 1000005
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
int nxt[maxn];
char p[maxn];
int m, x, ans;
int main(){
scanf("%s", p+1);
while(strcmp(p+1,".") !=0){
m = strlen(p+1);
nxt[0] = -1;
int j = -1;
for(int i=1; i<=m; i++){
while(j>=0 && p[j+1]!=p[i]) j=nxt[j];
nxt[i] = ++j;
}
// 第一个前缀
x = nxt[m];
while(x!=-1){
if(m % (m-x) == 0){
ans = m-x;
break;
}
x = nxt[x];
}
cout << m/ans << endl;
scanf("%s",p+1);
}
return 0;
}