题目

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] 也是回文串
  • 长度为12时的子串需单独判断
  • 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分) 中心扩展法+动态规划的更多相关文章

  1. PAT 甲级 1040 Longest Symmetric String (25 分)(字符串最长对称字串,遍历)

    1040 Longest Symmetric String (25 分)   Given a string, you are supposed to output the length of the ...

  2. pat1040. Longest Symmetric String (25)

    1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...

  3. 1040 Longest Symmetric String (25分)(dp)

    Given a string, you are supposed to output the length of the longest symmetric sub-string. For examp ...

  4. 【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))

    题意: 输入一个包含空格的字符串,输出它的最长回文子串的长度. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include<bits/std ...

  5. 1040. Longest Symmetric String (25)

    题目链接:http://www.patest.cn/contests/pat-a-practise/1040 题目: 1040. Longest Symmetric String (25) 时间限制 ...

  6. PAT1040:Longest Symmetric String

    1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...

  7. PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  8. PAT (Advanced Level) 1040. Longest Symmetric String (25)

    暴力. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ]; ...

  9. PAT 1040 Longest Symmetric String[dp][难]

    1040 Longest Symmetric String (25)(25 分) Given a string, you are supposed to output the length of th ...

随机推荐

  1. 关于web标准

    从我去年接触前端,到现在,我似乎都没有特意去研究过web标准.我只知道传统上推崇结构样式行为分离,js.css.html各司其职, 不推荐在文档的节点上写类似<p onclick=“fn()”& ...

  2. mysql运维入门2:主从架构

    mysql主从原理 随着访问量的增加,数据库压力的增加,需要对msyql进行优化和架构改造,优化方法有: 高可用 主从复制 读写分离 拆分库 拆分表 原理 异步复制过程 master开启bin-log ...

  3. 在ORACLE中实现SELECT TOP N的方法----[转]

    1.在ORACLE中实现SELECT TOP N 由于ORACLE不支持SELECT TOP语句,所以在ORACLE中经常是用ORDER BY跟ROWNUM的组合来实现SELECT TOP N的查询. ...

  4. ShoneSharp语言(S#)的设计和使用介绍系列(8)— 最炫“公式”风

    ShoneSharp语言(S#)的设计和使用介绍 系列(8)— 最炫“公式”风 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSha ...

  5. Spring Boot 教程(1) - HelloWorld

    Spring Boot 教程 - HelloWorld 1. Spring Boot 的由来 大家都知道,Spring框架是Java生态中举足轻重的轻量型框架,帮助我们广大的大佬们进行Java开发.S ...

  6. PHP非常用函数汇总

    1) ARRAY_FILTER — 用回调函数过滤数组中的单元 function  odd ( $var ) {      // returns whether the input integer i ...

  7. wordpress中文章发布时间不显示?用get_the_date代替the_date

    今天发现,在主题中部分地方使用the_date函数来显示文章发布的时间时,竟然发生不显示时间的情况,再仔细看了一下这些文章,有些都是经过几次修改和保存的,可能是由于the_date只是显示文章第一次发 ...

  8. 格雷码 CSP(NOIP??)2019 洛谷 P5657

    洛谷AC通道! 多年过后,重新来看这道D1T1,20min不到AC,再回忆起当初考场三小时的抓耳挠腮,不禁感慨万千啊!! 发篇题解记录一下. 思路:直接dfs模拟即可(二进制找规律是不可能的, 这辈子 ...

  9. BZOJ1001 狼抓兔子 题解

    裸的最小割,转化成最大流即可. #include <bits/stdc++.h> int n,m; int S,T; int mincost; int head[6001000],tot= ...

  10. Chisel3 - util - OneHot

    https://mp.weixin.qq.com/s/Jsy8P3m9W2EYKwneGVekiw   独热码相关的电路生成器.   参考链接: https://github.com/freechip ...