• [USACO 6.2.1] Calf Flac


    题目大意

      给出一份文本文档,要求在这份文档中找出最长回文串(回文串忽略符号,即只包含大小写字母),并输出原文(即符号也要输出).

    题解

      实际上不就是一个manacher算法模板题嘛.

      但是首先要忽略了符号,注意,回车换行符也算是一个符号.

      manacher算法实际上就是一个DP.网上有很多资料,这里不再细说.

      然后在manacher的过程中加入记录字符在原文中的位置即可.

    代码

    /*
    TASK:calfflac
    LANG:C++
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int MAXN = 20005;
    
    char text[MAXN + 1000], mc[MAXN * 2];
    int f[MAXN * 2], key[MAXN * 2], totlen, n, maxr, ans;
    
    bool check(char c)
    {
        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
    }
    
    char upcase(char c)
    {
        if (c >= 'A' && c <= 'Z') return c;
        else return c - 'a' + 'A';
    }
    
    int main()
    {
        freopen("calfflac.in", "r", stdin);
        freopen("calfflac.out", "w", stdout);
        totlen = 0;
        while (fgets(mc, 100, stdin))
        {
            n = strlen(mc);
            for (int i = totlen; i < totlen + n; ++i)
                text[i] = mc[i - totlen];
            totlen += n;
        }
        n = 0;
        memset(mc, 0, sizeof(mc));
        for (int i = 0; i < totlen; ++i)
            if (check(text[i])) mc[n++] = upcase(text[i]), key[n-1] = i, mc[n++] = '#';
        memset(f, 0, sizeof(f));
        maxr = 0;
        ans = 0;
        for (int i = 1; i < n; ++i)
        {
            if (maxr + f[maxr] >= i)
            {
                int j = 2 * maxr - i;
                if (j - f[j] >= maxr - f[maxr]) f[i] = f[j];
                else
                {
                    int l = 0;
                    f[i] = j - maxr + f[maxr];
                    while (mc[i - f[i] - l - 1] == mc[i + f[i] + l + 1]) l++;
                    f[i] += l;
                    if (mc[i + f[i]] == '#' && f[i] > 0) f[i]--;
                    if (maxr + f[maxr] < i + f[i]) maxr = i;
                    if (f[ans] < f[i]) ans = i;
                }
            }
            else
            {
                int l = 0;
                while (mc[i - l - 1] == mc[i + l + 1]) l++;
                f[i] = l;
                if (mc[i + f[i]] == '#' && f[i] > 0) f[i]--;
                if (maxr + f[maxr] < i + f[i]) maxr = i;
                if (f[ans] < f[i]) ans = i;
            }
        }
        printf("%d
    ", f[ans] + 1);
        for (int i = key[ans - f[ans]]; i <= key[ans + f[ans]]; ++i) printf("%c", text[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    oracle索引
    linux命令
    struts2的配置文件struts.xml详解
    oracle删除一个表中的重复数据,且只保留一条
    初步研究java类的加载机制
    java读取Properties配置文件
    利用oracle闪回来找回被drop的表
    快速排序Quicksort
    树与树的概念
    递归
  • 原文地址:https://www.cnblogs.com/albert7xie/p/5732715.html
Copyright © 2020-2023  润新知