• [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;
    }
  • 相关阅读:
    JS提取子字符串函数比较
    js事件定义方式和获取事件对象event总结
    让body的clientHeight与html的clientHeight相等的方法
    关于原型链和继承问题的思考:为什么不能直接把父类的prototype赋值给子类的prototype
    [javascript权威指南笔记02]Throw语句和异常处理机制try/catch/finally
    转载:javascript语句标签
    转:JS中强大的正则表达式
    分享我常用的Javascript工具函数
    对prototype,instanceof和constrctor的理解
    xml基础知识总结和回顾
  • 原文地址:https://www.cnblogs.com/albert7xie/p/5732715.html
Copyright © 2020-2023  润新知