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

题意

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

传送门

思路

最小/大表示法求下标,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
", mi+1, cnt, mx+1, cnt);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/acerkoo/p/11516837.html