[USACO 1.3.3]Calf Flac

o(︶︿︶)o 烦躁,看了半天没看懂这个O(n)的回文串算法是什么东西,直接套上模板就交了。然后AC了

题目:

Description

 

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

 

Input

 

一个不超过20,000个字符的文件。

 

Output

 

输出的第一行应该包括找到的最长的回文的长度。下一个行或几行应该包括这个回文的原文(没有除去标点符号、空格), 把这个回文输出到一行或多行(如果回文中包括换行符)。如果有多个回文长度都等于最大值,输出那个前出现的。

 

Sample Input

 

Confucius say: Madam, I'm Adam.

 

Sample Output

 

11 Madam, I'm Adam
#include<string>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char a[200005],b[400005];
int p[400005],mark[400005];
void pk(char *str)
{int i;int mx = 0;int id,n=strlen(str);for(i=1; i<n; i++){if( mx > i )p[i] = min( p[2*id-i], mx-i );        elsep[i] = 1;for(; str[i+p[i]] == str[i-p[i]]; p[i]++);if( p[i] + i > mx ){mx = p[i] + i;id = i;}}
}
int main()
{int i,j,k;while(gets(a)){int len=strlen(a);b[0]='#';for(i=0,j=1;i<len;++i){if(a[i]>='a'&&a[i]<='z'){mark[j]=i;b[j++]=a[i];b[j++]='#';}else if(a[i]>='A'&&a[i]<='Z'){mark[j]=i;b[j++]=a[i]+32;b[j++]='#';}}b[j]=0;pk(b);int ans=0,n=strlen(b),re=0;for(i=0;i<n;++i)if(p[i]>ans){ans=p[i];re=i;}int ok,ko;ans--;ok=re-ans+1;ko=re+ans-1;printf("%d\n",ans);for(i=mark[ok];i<=mark[ko];++i)printf("%c",a[i]);printf("\n");}return 0;
}

 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如$#a#b#a#。

下面以字符串12212321为例,经过上一步,变成了 S[] = "$#1#2#2#1#2#3#2#1#";



然后用一个数组 P[i] 来记录以字符S[i]为中心的最长回文子串向左/右扩张的长度(包括S[i]),比如S和P的对应关系:

那么怎么计算P[i]呢?该算法增加两个辅助变量(其实一个就够了,两个更清晰)id和mx,其中id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界。

然后可以得到一个非常神奇的结论,这个算法的关键点就在这里了:如果mx > i,那么P[i] >= MIN(P[2 * id - i], mx - i)。就是这个串卡了我非常久。实际上如果把它写得复杂一点,理解起来会简单很多:

当然光看代码还是不够清晰,还是借助图来理解比较容易。

当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于 i 和 j 对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 P[i] = P[j],见下图。
点击在新窗口中浏览此图片

当 P[j] > mx - i 的时候,以S[j]为中心的回文子串不完全包含于以S[id]为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,就只能老老实实去匹配了。
点击在新窗口中浏览此图片

对于 mx <= i 的情况,无法对 P[i]做更多的假设,只能P[i] = 1,然后再去匹配了。

转载于:https://www.cnblogs.com/A-way/archive/2013/05/10/3071519.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[libuv] libuv学习

From: https://www.mobibrw.com/2016/3490 libuv 是重写了下libev&#xff0c;封装了windows和unix的差异性。 libuv的特点 非阻塞TCP套接字 socket&#xff1f; 非阻塞命名管道 UDP 定时器 子进程 fork? 通过 uv_getaddrinfo实现异步DNS 异步文件系统API uv_fs_* 高分辨率时…

elemnt的Table 表格使用注意事项

elemnt的Table 表格使用注意事项 1、修改数据 <template slot-scope"scope"><el-button size"mini" clickupdatePassword(scope.row)>修改密码</el-button><el-button size"mini" clickresetPassword(scope.row)>重置密…

px、em、rem、vm、vw 、vh、vmin 、vmax区分

Px表示“绝对尺寸”&#xff08;并非真正的绝对&#xff09;&#xff0c;实际上就是css中定义的像素&#xff08;此像素与设备的物理像素有一定的区别&#xff0c;后续详细说明见文末说明1&#xff09;&#xff0c;利用px设置字体大小及元素宽高等比较稳定和精确。Px的缺点是其…

Class.forName()用法详解

Class.forName()用法详解 标签&#xff1a; classjvmjdbc数据库documentationjava2012-03-29 09:39 40414人阅读 评论(8) 收藏 举报分类&#xff1a;Java考古学&#xff08;74&#xff09; 主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要…

[poco] 访问数据库

From: https://blog.csdn.net/hl2015222050145/article/details/52335422?utm_sourceblogxgwz6 poco访问数据基本步骤&#xff1a; a. 创建会话(session) b. 从DB中读写数据 c. 使用statements d. 使用容器&#xff08;Collection&#xff09; (数据&#xff0c;集合...) …

应对不良网络文化的技术之一——网络信息抽取技术

1 引言 2008年1月17日&#xff0c;中国互联网络信息中心(CNNIC)发布了《第21次中国互联网络发展状况统计报告》[1]&#xff0c;报告显示&#xff1a; (1) 截至2007年12月&#xff0c;网民数已增至2.1亿人。中国网民数增长迅速&#xff0c;比2007年6月增加4800万人&…

最安全的js类型检测

众所周知js内置的类型检测机制不可靠&#xff0c;比如typeof操作符&#xff0c;对于正则和数组检测时返回值都是object&#xff0c; 而使用instanceof检测类型时&#xff0c;虽然可以对正则和数组正常验证&#xff0c;但验证undefined会报错&#xff0c;还有对于Symbol无法验证…

HBuilder完成webApp入门(2)

一、HBuilder的下载地址&#xff1a;http://www.dcloud.io/&#xff0c;点击那个“DownLoad”就可以 了 二、假设一切顺利&#xff0c;启动HBuilder后&#xff0c;大家会看到如下的界面 点击新建移动APP&#xff1a; 接下来就会弹出一个选择模板的对话框&#xff1a; 默认的模板…

js防篡改对象之不可扩展对象

const person {name: 啦啦德玛西亚}console.log(Object.isExtensible(person))//true//使用Object.preventExtensions()可以将对象修改为不可扩展对象&#xff0c;无法再给对象添加属性和方法Object.preventExtensions(person)//使用Object.isExtensible()方法可以确定对象是否…

高可用集群 heartbeatv1实例

——————— 高可用集群的简单配置 ————————地址规划 主节点&#xff1a;HA1 172.16.21.13 hostname node2.magedu.com备节点&#xff1a; HA2 172.16.21.14 hostname node1.magedu.comVIP 172.16.21.9前提工作1&#xff0c;配置主机名 hostname保证uname …

你知道“拉黑”、“关注”、“点赞”、“转发”、“分享到朋友圈”等英语咋说吗?

From: https://www.sohu.com/a/220161051_559507 “分享到朋友圈”等英语咋说吗&#xff1f; Mini apps 小程序 小程序”&#xff08;mini apps&#xff09;是一个不需要下载安装就可使用的应用&#xff08;apps that can be accessed without downloading&#xff09;&#x…

C#进化史

C#进化史 C#进化史从数据类型看C#演化C# 1写的产品类C# 强类型集合——解决限制1和2c# 自动属性——解决限制3c# 4 命名实参C# 1~C# 4的演变历程排序C# 1——提供一个IComparer实现C# 2——泛型比较器C# 3——Lambda表达式、扩展方法C# 1~C# 3简化排序的历程查询集合C# 1——循…

防篡改对象之密封对象

const person {name: 啦啦德玛西亚}console.log(Object.isExtensible(person))// trueconsole.log(Object.isSealed(person))// false// 使用Object.seal()将对象修改为密封对象// 密封对象不可扩展&#xff0c;而且已有成员的[[Configurable]]特性将被设置为false// 意味着不…

配套自测连载(三)

接上期(答案已给出)本期是专门针对《深入理解计算机网络》图书第4章而编写的10道计算机网络体系架构中的物理层技术自测题&#xff0c;可以检验你对本章的学习效果。把你的答案直接写在评论中即可&#xff0c;笔者将在每期发表10天后给出正确答案。本书是国内最通俗、最系统的计…

[json] JSON for Modern C++

有幸能接触到这个&#xff0c;这是我遇到的使用最方便的json了&#xff0c;效率没研究过&#xff01; 简单了使用了下&#xff0c;感觉非常好用&#xff0c;记录下&#xff1a; 要使用这个json&#xff0c;只需要使用json.hpp就行&#xff0c;放入自己的工程里&#xff0c;但…

面向对象的需求分析方法

面向对象的需求分析方法 面向对象的需求分析方法的核心是利用面向对象的概念和方法为软件需求建造模型。它包含面向对象风格的图形语言机制和用于指导需求分析的面向对象方法学。 面向对象的思想最初起源于 20世纪 60年代中期的仿真程序设计语言Simula67。20世纪80年代初出现的…

js防篡改对象之冻结对象

const person {name: 啦啦德玛西亚,_job: 无业}Object.defineProperty(person, job, {get: function() {return this._job},set: function(newValue) {this._job newValue}})console.log(Object.isFrozen(person))// false//使用Object.freeze()将对象修改为冻结对象&#xf…

libinject的编译

libinject是一个Android进程注入实例&#xff0c;其下载地址为&#xff1a;http://download.csdn.net/download/ljhzbljhzb/3680780 libinject的编译需要NDK开发环境&#xff0c;在NDK安装成功之后&#xff0c;可以先将其自带的实例中的HelloJni导入到eclipse中&#xff0c;编译…

Boost - 序列化 (Serialization)

From: https://blog.csdn.net/zj510/article/details/8105408 程序开发中&#xff0c;序列化是经常需要用到的。像一些相对高级语言&#xff0c;比如JAVA, C#都已经很好的支持了序列化&#xff0c;那么C呢&#xff1f;当然一个比较好的选择就是用Boost&#xff0c;这个号称C准…

Linux Supervisor 守护进程基本配置

supervisor:C/S架构的进程控制系统&#xff0c;可使用户在类UNIX系统中监控、管理进程。常用于管理与某个用户或项目相关的进程。 组成部分supervisord&#xff1a;服务守护进程supervisorctl&#xff1a;命令行客户端Web Server&#xff1a;提供与supervisorctl功能相当的WEB操…