PAT1040 Longest Symmetric String (25分) 中心扩展法+动态规划
题目
Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, given Is PAT&TAP symmetric?, the longest symmetric sub-string is s PAT&TAP s, hence you must output 11.
Input Specification:
Each input file contains one test case which gives a non-empty string of length no more than 1000.
Output Specification:
For each test case, simply print the maximum length in a line.
Sample Input:
Is PAT&TAP symmetric?
Sample Output:
11
题目解析
给定一个字符串,要求输出它最长回文子串的长度。
什么是回文子串,就是类似 baab aacaa
这种中心对称的字符串。
注意,输入字符串可能包括空格,所以这里使用getline(cin,str)
思路一:中心扩展法
所谓中心扩展法,就是从回文串“中心对称”这个特点来的。
我们先分析一下这个“对称”,如果是奇数长度的字符串,那么它关于最中心的那个字符对称;如果是偶数长度的字符串,它的对称线是最中心两个字符的中间画一条线(比如baab
),也就是关于最中心两个字符(aa
)是对称的(那两个字符是一样的)
所以中心扩展法的思路就是,把某个位置作为中间位置,向两边扩展,直到左右指针对应位置字符不等。
那么对于一个字符串,中心位置如何取,如果以每个字符作为中心,那么我们就能找到它所有长度为奇数的最长对称串的长度,以连续两个字符作为中心,救能得到所有长度为偶数的最长的对称串的长度,然后我们再二者之间取最大值即可。
文字描述比较抽象,直接看代码,挺容易理解的。
#include <iostream>
using namespace std;
// 中心扩展法
int helper(string s, int leftborder,int l,int r,int rightborder) {
// 向两端无限扩展
while(leftborder <= l && s[l] == s[r] && r <= rightborder) {
--l;++r;
}
// 已记录的有效回文串长度
return r - l - 1;
}
int main() {
string s;
getline(cin, s);
int len = s.length();
int res = 0;
for (int i = 0; i < len; ++i) {
// 以本身为中心,像左右扩展
int len1 = helper(s, 0, i, i, len - 1);
// 以自己和下一个字符为中心,向左右扩展
int len2 = helper(s, 0, i, i + 1, len - 1);
res = max(res, len1);
// 总是取更大那个
res = max(res, len2);
}
cout << res;
}
思路二:动态规划
思路一里面对于每个字符都要进行两次中心扩展,肯定进行了很多次重复操作,而动态规划就是为解决重复操作而生的。
把一个字符串表示为 s[0],s[1]...s[i],s[i+1],s[i+2]...s[j-2],s[j-1],s[j]...s[len-1]
- 如果
s[i+1,j-1]
是回文串,那么只要s[i] == s[j]
,就可以确定s[i][j]
也是回文串 - 长度为
1
和2
时的子串需单独判断 dp[i][j]
代表s[i][j]
是不是回文子串
动态规划的核心就是由子问题状态保留,不再重新计算,对于一个长度为len
的字符串,它的每个子串长度可以是 1到len
,我们从小到大取出所有长度的子串进行判断。
#include<iostream>
using namespace std;
int main() {
string s;
getline(cin, s);
int len = s.length();
int res = 0;
bool dp[len][len] = {false};
int maxLen = 0;
//对于所有长度的子串
for (int len = 1; len <= s.length(); len++)
for (int i = 0; i < s.length(); i++) {
int j = i + len - 1; // i是起点,j是终点,长度是len
// 当前情况不可能,不存在从i开始长为len的子串
if (j >= s.length()) break;
//长度是1就是单个字符,满足回文
if (len == 1) dp[i][j] = true;
// 长度是2就看这两个字符是否相等
else if (len == 2) dp[i][j] = s[i] == s[j];
// 否则,如果 S[i+1,j-1] 是回文串,只要 S[i] == S[j],S[i][j]也是回文串
else dp[i][j] = dp[i + 1][j - 1] && s[i] == s[j];
// 当前串是回文串且比上一次的更长
if (dp[i][j] && len > maxLen) {
maxLen = len;
}
}
cout << maxLen;
return 0;
}
感觉动态规划会比中心扩展更快,但提交结果是中心扩展更快,真是脑壳痛。。
PAT1040 Longest Symmetric String (25分) 中心扩展法+动态规划的更多相关文章
- PAT 甲级 1040 Longest Symmetric String (25 分)(字符串最长对称字串,遍历)
1040 Longest Symmetric String (25 分) Given a string, you are supposed to output the length of the ...
- pat1040. Longest Symmetric String (25)
1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...
- 1040 Longest Symmetric String (25分)(dp)
Given a string, you are supposed to output the length of the longest symmetric sub-string. For examp ...
- 【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
题意: 输入一个包含空格的字符串,输出它的最长回文子串的长度. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include<bits/std ...
- 1040. Longest Symmetric String (25)
题目链接:http://www.patest.cn/contests/pat-a-practise/1040 题目: 1040. Longest Symmetric String (25) 时间限制 ...
- PAT1040:Longest Symmetric String
1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- PAT (Advanced Level) 1040. Longest Symmetric String (25)
暴力. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ]; ...
- PAT 1040 Longest Symmetric String[dp][难]
1040 Longest Symmetric String (25)(25 分) Given a string, you are supposed to output the length of th ...
随机推荐
- vue中使用mixins
Mixins (混合或混入)——定义的是一个对象 1.概念:一种分发Vue组件可复用功能的非常灵活的方式.混入对象可以包含任意组件选项(组件选项:data.watch.computed.methods ...
- Jquery学习2---倒计时
以下代码是mvc4.0代码,其功能是让页面上的数字3,变2,变1 然后跳转页面 @{ ViewBag.Title = "LoginOut"; } <html> < ...
- h5+ 开发分享功能
h5+ 开发微信.QQ分享功能 此处只做微信网页分享示例代码 方式一.JS+HTML+h5Plus 1.html代码 <div class="button" onclick= ...
- ssserver多出口ip
环境:centos6.10-7x(虚拟机),配置好之后至少保证能上网 需求:在一台服务器上配置多ip,并实现,用哪个ip 作为代理,访问ip138.com这类的网站的时候就返回对应的ip. 实现步骤: ...
- mysql创建本地用户及赋予数据库权限的方法示例
大家在安装 mysql 时通常会生成一个超级用户 root,很多人之后就一直沿用这一个用户,虽然这会很方便,但超级用户权限太大,在所有地方使用它通常是一个安全隐患. 这一点跟操作系统的用户管理也是类似 ...
- spring的mybatis-puls 配置,增删改查操作,分页
pom <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...
- PHP的图像函数
imagecreate() 和 imagecreatetruecolor() 函数用于创建一幅空白图像. imagedestroy() 函数用于销毁图像资源. imagecreate() 如果我们要对 ...
- 上位机开发之三菱FX3U以太网通信实践
上次跟大家介绍了一下上位机与三菱Q系列PLC通信的案例,大家可以通过点击这篇文章:上位机开发之三菱Q系列PLC通信实践(←戳这里) 今天以三菱FX3U PLC为例,跟大家介绍一下,如何实现上位机与其之 ...
- 【JUC】如何理解线程池?第四种使用线程的方式
线程池的概念 线程池的主要工作的控制运行的线程的数量,处理过程种将任务放在队列,线程创建后再启动折现任务,如果线程数量超过了最大的数量,则超过部分的线程排队等待,直到其他线程执行完毕后,从队列种取出任 ...
- Redis详解(十)------ 从零开始搭建集群
在上一篇博客我们介绍了------Redis哨兵(Sentinel)模式,哨兵模式主要是解决高可用问题,在master节点宕机时,slave节点能够自动切换成为master节点 本篇博客我们来介绍Re ...