[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\n", f[ans] + 1);
    for (int i = key[ans - f[ans]]; i <= key[ans + f[ans]]; ++i) printf("%c", text[i]);
    printf("\n");
    return 0;
}
时间: 2024-10-08 23:32:59

[USACO 6.2.1] Calf Flac的相关文章

USACO Section 1.3 : Calf Flac (calfflac)

题意:据说假设你给无限仅仅母牛和无限台巨型便携式电脑(有很大的键盘),那么母牛们会制造出世上最优秀的回文. 你的工作就是去寻找这些牛制造的奇观(最优秀的回文). 在寻找回文时不用理睬那些标点符号.空格(但应该保留下来以便做为答案输出),仅仅用考虑字母'A'-'Z'和'a'-'z'.要你寻找的最长的回文的文章是一个不超过20,000个字符的字符串. 我们将保证最长的回文不会超过2,000个字符(在除去标点符号.空格之前). 暴力 注意一些细节 输入字符中有回车啊之类的 wins下 输完按回车按Ct

USACO 1.3.3 Calf Flac(Manacher算法)

Description 据说如果你给无限只母牛和无限台巨型便携式电脑(有非常大的键盘),那么母牛们会制造出世上最棒的回文.你的工作就是去寻找这些牛制造的奇观(最棒的回文). 在寻找回文时不用理睬那些标点符号.空格(但应该保留下来以便做为答案输出),只用考虑字母'A'-'Z'和'a'-'z'.要你寻找的最长的回文的文章是一个不超过20,000个字符的字符串. 我们将保证最长的回文不会超过2,000个字符(在除去标点符号.空格之前). Input 输入文件不会超过20,000字符.这个文件可能一行或

ACM中常用算法----字符串

ACM中常用算法--字符串 ACM中常用的字符串算法不多,主要有以下几种: Hash 字典树 KMP AC自动机 manacher 后缀数组 EX_KMP SAM(后缀自动机) 回文串自动机 下面来分别介绍一下: 0. Hash 字符串的hash是最简单也最常用的算法,通过某种hash函数将不同的字符串分别对应到不同的数字.进而配合其他数据结构或STL可以做到判重,统计,查询等操作. #### 字符串的hash函数: 一个很简单的hash函数代码如下: ull xp[maxn],hash[max

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI

转载:hdu 题目分类 (侵删)

转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029. 1032.1037.1040.1048.1056.1058.1061.1070.1076.1089.1090.1091.1092.1093. 1094.1095.1096.1097.1098.1106.1108.1157.116

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

USACO prefix TrieTree + DP

/* ID:kevin_s1 PROG:prefix LANG:C++ */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib>

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f