码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3374 String Problem(最小值表示法 + KMP)

时间:2019-09-13 15:47:57      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:scan   php   scanf   次数   amp   using   i+1   开始   har   

题意

给一个循环串,从某个点开始会得到一个字典序最小的串,从某个点开始会得到一个字典序最大的串,求这两个点的下标,以及其出现的次数。

传送门

思路

最小/大表示法求下标,kmp求出现次数。

最小/大表示法

Code

#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 1e6+10;

int nxt[maxn], l;
char str[maxn<<1];

void getNxt(char *p) {
    for (int i=1, j = 0; p[i]; ++i) {
        while(j && p[i]!=p[j]) j = nxt[j-1];
        if(p[i] == p[j]) ++j;
        nxt[i] = j;
    }
}

int solve(int op) {  // 0: 最小表示法, 1:最大表示法
    strncpy(str+l, str, l);
    int i = 0, j = 1;
    while(i < l && j < l) {
        int k = 0;
        while(k < l && str[i+k] == str[j+k]) ++k;
        if(k >= l) break;
        if((str[i+k] > str[j+k]) ^ op) i += k+1;
        else j += k+1;
        if(i == j) ++j;
    }
    return i < j ? i : j;
}

int main() {
    while(scanf("%s", str)==1) {
        getNxt(str);
        l = strlen(str);
        int len = l - nxt[l-1], cnt = l % len ? 1 : l/len;
        int mi = solve(0), mx = solve(1);
        printf("%d %d %d %d\n", mi+1, cnt, mx+1, cnt);
    }
    return 0;
}

hdu3374 String Problem(最小值表示法 + KMP)

标签:scan   php   scanf   次数   amp   using   i+1   开始   har   

原文地址:https://www.cnblogs.com/acerkoo/p/11516837.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!