hdu 3374 String Problem(最小表示法+kmp)

来源:互联网 发布:淘宝运费险赔付金额 编辑:程序博客网 时间:2024/05/13 21:18

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3374

解题思路:

题目大意:

给你一个字符串,每次将最前一个字符放到最后,直到形成一周,然后按照每个字符串出现的先后排个名次,现在要你求出字典序

最小的字符串和字典序最大的字符串为RANK几。并输出它们的出现次数,如果出现次数不只一次,那么输出RANK值较小的。

算法思想:

先用kmp求出循环节,再用最小表示法,分别求出字典序最小的字符串和字典序最大的字符串为RANK几。

最小表示法模板:

http://blog.csdn.net/piaocoder/article/details/48447193

AC代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 1000005;char str[maxn];int Next[maxn];void getNext(char *p){    int len = strlen(p);    int j = 0,k = -1;    Next[0] = -1;    while(j < len){        if(k==-1 || p[j]==p[k]){            j++; k++;            Next[j] = k;        }        else            k = Next[k];    }}int minRepresstation(char *s,bool flag = true){    int len = strlen(s);    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)                i += k+1;            else                j += k+1;            if(i == j)                j++;            k = 0;        }    }    return min(i,j);}int main(){    while(~scanf("%s", str)){        int len,minlen,num;        len = strlen(str);        getNext(str);        if (len % (len-Next[len]) == 0)            minlen = len-Next[len];        else            minlen = len;        num = len / minlen;        printf("%d %d %d %d\n",minRepresstation(str)+1,num,minRepresstation(str,false)+1,num);    }    return 0;}


0 0
原创粉丝点击