题意:字符串的最大表示法和最小表示法出现了多少次。
思路:循环节的个数就是出现的次数。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000005;
int get_minstring(char *s) //最小表示法
{
int len=strlen(s);
int i=0,j=1,k=0;
while(i<len&&j<len&&k<len)
{
int t=s[(i+k)%len]-s[(j+k)%len];
if(t==0)
k++;
else
{
if(t>0)
i=i+k+1;
else
j=j+k+1;
if(i==j)
j++;
k=0;
}
}
return min(i,j);
}
int get_maxstring(char *s) //最大表示法
{
int len=strlen(s);
int i=0,j=1,k=0;
while(i<len&&j<len&&k<len)
{
int t=s[(i+k)%len]-s[(j+k)%len];
if(t==0)
k++;
else
{
if(t>0)
j=j+k+1;
else
i=i+k+1;
if(i==j)
j++;
k=0;
}
}
return min(i,j);
}
char str[maxn];
int f[maxn];
void get_fail( char* P,int *f ){
f[0] = -1;
int m = strlen(P);
for( int i = 1;i < m;i++ ){
int j = f[i-1];
while( j != -1 && P[j+1]!=P[i] )j = f[j];
if( P[j+1]==P[i] ) f[i] = j+1;
else f[i] = -1;
}
}
int main(){
while( scanf("%s",str) != EOF ){
int len =strlen(str);
get_fail( str,f );
int p = len - f[len-1]-1;
int res = 1;
if( len%p == 0 ){
res = len/p;
}
int pos1 = get_minstring( str);
int pos2 = get_maxstring( str);
printf("%d %d %d %d\n",pos1+1,res,pos2+1,res);
}
return 0;
}