Period
题目大意:
有多组测试用例,第一行为字符串长度,第二行为字符串,则对字符串的每一个前缀,若存在循环节且循环次数>1,输出长度和最大的循环次数;
每组测试用例后空一行;
SampleInput
3
aaa
12
aabaabaabaab
0
SampleOutput
Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4
分析:KMP算法,判断错位部分能否成为最小循环节即可;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <unordered_map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define Lson L, mid, ls[rt] #define Rson mid+1, R, rs[rt] #define sys system("pause") #define freopen freopen("in.txt","r",stdin) const int maxn=1e6+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline ll read() { ll x=0;int f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int n,m,k,t,nxt[maxn],cas; char a[maxn]; int main() { int i,j; while(~scanf("%d",&n)&&n) { scanf("%s",a); nxt[0]=-1,j=-1; for(i=0;i<n;) { if(j==-1||a[i]==a[j])nxt[++i]=++j; else j=nxt[j]; } printf("Test case #%d\n",++cas); for(i=2;i<=n;i++) { if(nxt[i]>0&&i%(i-nxt[i])==0) printf("%d %d\n",i,i/(i-nxt[i])); } puts(""); } //system("Pause"); return 0; }
时间: 2024-11-09 12:28:24