USACO Section 1.3 Calf Flac

manacher求最长子串。

/*
PROG : calfflac
LANG : C++
*/

# include <cstdio>
# include <cctype>

# define N 20000 + 5

int n;
char s[N];

int Min(int x, int y)
{
    return x < y ? x : y;
}

int manacher(char *s, int len, int &st)
{
    int n = len*2+1;
    char t[2 * N];

    /*  insert '#' in string s to form a 2*len+1 string t
         在 s 中插入 len+1 个 '#' 使 s 中的奇偶回文字符串统一起来   */
    for (int i = 0; i < len; ++i)
    {
        t[2*i] = '#';
        t[2*i+1] = s[i];
    }
    t[n-1] = '#';

    int ret = 0;
    int p[2 * N];
    int mx = 0, id;
    for (int i = 1; i < n; ++i)
    {
        p[i] = mx>i ? Min(p[2*id-i], mx-i):1;
        while (t[i-p[i]] == t[i+p[i]]) ++p[i];
        if (i+p[i] > mx) mx = i+p[i], id = i;
        /*  find the longest sub-palindrome,
            set ret and st(start position of LSP in s) */
        if (p[i]-1 > ret)
        {
            ret = p[i] - 1;
            st = (i-p[i]+1)/2;
        }
    }
    return ret;
}

void solve(void)
{
    int st;
    int r[N];
    char ss[N];
    int k = 0;
    for (int i = 0; i < n; ++i)
    {
        if (isalpha(s[i]))
        {
            r[k] = i;
            ss[k++] = tolower(s[i]);
        }
    }
    int len = manacher(ss, k, st);
    s[r[st+len-1]+1] = 0;
    printf("%d\n%s\n", len, s+r[st]);
}

int main()
{
    freopen("calfflac.in", "r", stdin);
    freopen("calfflac.out", "w", stdout);

    n = 0;
    while ((s[n++]=getchar()) != EOF) ;

    solve();

    fclose(stdin);
    fclose(stdout);

    return 0;
}

manacher的资料;

Finding the Longest Palindromic Substring in Linear Time

Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串

posted on 2012-08-05 08:25  getgoing  阅读(217)  评论(0编辑  收藏  举报

导航