Revolving Digits
For each test cases, there is only one line that is the original integer N. we will ensure that N is an positive integer without leading zeros and N is less than 10^100000.
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int N=100500;
char s[2*N],t[N];
int ext[N],extand[N];
int slen,tlen,len;
int get_len(char t[])
{
int i=0,j=-1;
ext[0]=-1;
while(i<tlen)
{
if(j==-1||t[i]==t[j])
ext[++i]=++j;
else
j=ext[j];
}
return tlen-ext[tlen];
}
void getnext(char T[]){// next[i]: 以第i位置開始的子串 與 T的公共前綴
int i,length = strlen(T);
ext[0] = length;
for(i = 0;i<length-1 && T[i]==T[i+1]; i++);
ext[1] = i;
int a = 1;
for(int k = 2; k < length; k++){
int p = a+ext[a]-1, L = ext[k-a];
if( (k-1)+L >= p ){
int j = (p-k+1)>0? (p-k+1) : 0;
while(k+j<length && T[k+j]==T[j]) j++;// 枚舉(p+1,length) 與(p-k+1,length) 區間比較
ext[k] = j, a = k;
}
else ext[k] = L;
}
}
void getextand(char S[],char T[]){
memset(ext,0,sizeof(ext));
getnext(T);
int a = 0;
int MinLen = slen>tlen?tlen:slen;
while(a<MinLen && S[a]==T[a]) a++;
extand[0] = a, a = 0;
for(int k = 1; k < slen; k++){
int p = a+extand[a]-1,L= ext[k-a];
if( (k-1)+L >= p )
{
int j = (p-k+1)>0? (p-k+1) : 0;
while(k+j<slen && j<tlen && S[k+j]==T[j] ) j++;
extand[k] = j;a = k;
}
else extand[k] = L;
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",t);
strcpy(s,t);
strcat(s,t);
slen=strlen(s);
tlen=strlen(t);
len=get_len(t);//循環節
if(tlen%len!=0)
len=tlen;
getextand(s,t);
int s1(0),s2(0),s3(0);
for(int j=0;j<len;j++)
{
if(extand[j]>=tlen)//也可以不用判斷 s2一定爲1
s2++;
else if(s[extand[j]+j]<s[extand[j]])
s1++;
else if(s[extand[j]+j]>s[extand[j]])
s3++;
}
printf("Case %d: ",i);
printf("%d %d %d\n",s1,s2,s3);
}
return 0;
}