题目链接:HDU3374
题目大意:给你一个字符串,项链一样的可以循环表示 例如“SKYLONG”可以有7中表示形式。
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
求出字典序最小和字典序最大的串以及他们的出现次数。
思路:
KMP求出循环节,最小表示法求出最小位置,最大位置
最小表示法模板题
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1000000 + 10;
char s[maxn];
int nextv[maxn];
int len;
void getNext(){ //KMP的next数组
int i = 0 , j = -1;
nextv[0] = -1;
while(i < len){
if(j == -1 || s[i] == s[j])
nextv[++i] = ++j;
else
j = nextv[j];
}
}
int minRepresentation(bool flag){
int i = 0,j = 1,k = 0;
while(i <len && j < len && k < len){
int tmp = s[(i + k)%len] - s[(j + k) % len];
if(tmp == 0) k++;
else{
if(flag? (tmp > 0):(tmp<0)) //如果 flag求出字典序最小,否则 求出最大
i += k+1;
else
j += k + 1;
if(i == j)
j ++ ;
k = 0;
}
}
return min(i,j);
}
int main(){
while(scanf("%s",s)!=EOF){
int minlen;
// memset(nextv,0,sizeof(nextv));
len = strlen(s);
getNext();
int length = len - nextv[len];
int num;
if (len % length == 0)
num = len /length; //如果出现循环节
else
num = 1;
printf("%d %d %d %d\n",minRepresentation(1)+1,num,minRepresentation(0)+1,num);
}
return 0;
}