字符串的最大最小表示法

来源:互联网 发布:农村淘宝怎么加盟 编辑:程序博客网 时间:2024/06/05 03:06

算法描述:给定一个字符串s,可以进行左循环(右循环)移位,总共的结果有strlen(s)种,在这些结果中最小的是那个,最大的是哪个。
详解描述
论文传送门
HDU3374
题目意思:给定一个字符串s求循环几次会是字典序最小的(最小表示),最大的(最大表示),分别会出现几次。
思路:第一个用上面提到算法就可以算,后面的只需要求出以为后的有几个循环就就好了。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1e6+10;int Next[maxn];int get_min(char s[])//最小表示法{    int len=strlen(s);    int i=0,j=1,k=0;    while(i<len&&j<len)    {        k=0;        while(s[(i+k)%len]==s[(j+k)%len]&&k<len)            k++;            if(k>=len) break;        if(s[(i+k)%len]>s[(j+k)%len])        {            i=i+k+1;            if(i==j)                i++;        }        else        {            j=j+k+1;            if(j==i)                j++;        }    }    return min(i,j);}int get_max(char s[])//最大表示法{    int len=strlen(s);    int i=0,j=1,k=0;    while(i<len&&j<len)    {        k=0;        while(s[(i+k)%len]==s[(j+k)%len]&&k<len)            k++;            if(k>=len) break;        if(s[(i+k)%len]<s[(j+k)%len])        {            i=i+k+1;            if(i==j)                j++;        }        else        {            j=j+k+1;            if(j==i)                i++;        }    }    return min(i,j);}void get_next(char s[]){    int len=strlen(s);    int i=0,j=-1;    Next[0]=-1;    while(i<len)    {        if(j==-1||s[i]==s[j])        {            i++,j++;            Next[i]=j;        }        else            j=Next[j];    }}char s[maxn],tmp1[maxn],tmp2[maxn];int main(){    while(~scanf("%s",&s))    {        int len=strlen(s);        int Min=get_min(s),Max=get_max(s),cont=0;        for(int i=Min; i<len; i++)            tmp1[cont++]=s[i];        for(int i=0; i<Min; i++)            tmp1[cont++]=s[i];        cont=0;        for(int i=Max; i<len; i++)            tmp2[cont++]=s[i];        for(int i=0; i<Max; i++)            tmp2[cont++]=s[i];            get_next(tmp1);            printf("%d %d ",Min+1,len%(len-Next[len])==0?len/(len-Next[len]):1);            get_next(tmp2);            printf("%d %d\n",Max+1,len%(len-Next[len])==0?len/(len-Next[len]):1);    }}
原创粉丝点击