HDU5442 Favorite Donut(KMP+最大表示法)

来源:互联网 发布:重庆seo网站推广 编辑:程序博客网 时间:2024/06/15 03:29

题意:给一个环,要找出里面的最大的串,输出串最大时起点的下标(从1开始)和顺时针(0)还是逆时针(1)。如果有多种情况就输出最小的下标,如果顺时针和逆时针相同就选择顺时针。


思路:正逆各用一次最大表示法即可。对于逆时针,因为要考虑字符串的循环对下标的影响,因此在与顺时针方向比较之前先做一次KMP,求出循环节长度。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<vector>#include<map>#include<algorithm>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const int mod = 1000000007;const int maxn = 20005;int MAXR(char s[], int l){for(int i=0; i<l; ++i){s[l + i] = s[i];}s[l * 2] = 0;int i = 0, j = 1;while(i < l && j < l){int k = 0;while(s[i + k] == s[j + k] && k < l){++k;}if(k == l) break;if(s[i + k] < s[j + k]) i = max(i + k + 1, j + 1);else j = max(j + k + 1, i + 1);}return i < j ? i : j;}void get_next(char s[], int next[]){    int len = strlen(s);    next[0] = -1;    int index;    for(int i=1; i<len; ++i){        index = next[i - 1];        while(index >= 0 && s[i] != s[index + 1]){            index = next[index];        }        if(s[i] == s[index + 1]){            next[i] = index + 1;        } else {            next[i] = -1;        }    }}char s1[maxn * 2], s2[maxn * 2];int nxt[maxn];int main(){    int len, t;    scanf("%d", &t);    while(t--){        scanf("%d", &len);        scanf("%s", s1);        for(int i=0; i<len; ++i){            s2[len - 1 - i] = s1[i];            s2[len] = 0;        }        get_next(s1, nxt);        int k = len;//k是循环节长度        if(nxt[len - 1] > -1 && len % (len - 1 - nxt[len - 1]) == 0){            k = len - 1 -nxt[len - 1];        }        int pos1 = MAXR(s1, len);        int pos2 = MAXR(s2, len);        s1[pos1 + len] = 0;        s2[pos2 + len] = 0;        if(strcmp(s1 + pos1, s2 + pos2) > 0){            printf("%d %d\n", pos1 + 1, 0);        } else if(strcmp(s1 + pos1, s2 + pos2) < 0) {            printf("%d %d\n", k - pos2, 1);        } else {            if((k - pos2) < (pos1 + 1)){                printf("%d %d\n", k - pos2, 1);            } else {                printf("%d %d\n", pos1 + 1, 0);            }        }    }}


阅读全文
0 0