hdu5340—Three Palindromes—(Manacher算法)——回文子串
Three Palindromes
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1948 Accepted Submission(s): 687
For each test case , there is an single line contains a string S which only consist of lowercase English letters.1≤|s|≤20000
题意:给出一个字符串,问能否将字符串分为三段,并且每一段的是回文串。
思路:这题要用到manacher算法,不知道的可以看一下这篇博客:https://blog.csdn.net/dyx404514/article/details/42061017。
首先用manacher求出以每个点为中点的回文串的半径,然后,我们可以知道,要将字符串分为三段,那第一段一定包含第一个字符,第三段一定包含最后一个字符。然后判断第一个回文串和第三个之间剩下的字符是否构成回文串就行了。
所以,我们找到用manacher算法求出的所有回文串中,包含了第一个字符和和最后一个字符的有那些,然后两两配对,看看是否存在某一对,他们不重合,且之间剩下的字符也是回文串。
具体操作看代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#define eps 1e-7
#define ll long long
#define inf 0x3f3f3f3f
#define pi 3.141592653589793238462643383279
using namespace std;
const int maxn = ;
char a[maxn],s_new[maxn<<];
int s_len[maxn<<]; int Init() //manacher算法初始化(模板)
{
int len = strlen(a);
s_new[] = '@';
int j = ;
for(int i=; i<len; ++i) //在每个字符左右插入'#'
{
s_new[j++] = '#';
s_new[j++] = a[i];
}
s_new[j++] = '#';
s_new[j] = '\0';
return j;
} void manacher(int len) //计算以每个点为中心的回文串的半径(模板)
{
int high = ,flag = ;
for(int i=; i<len; ++i)
{
if(i < high)
s_len[i] = min(high-i+ , s_len[*flag-i]);
else
s_len[i] = ; while(s_new[i + s_len[i]] == s_new[i - s_len[i]])
s_len[i]++; if(i + s_len[i] - > high)
{
high = i+ s_len[i] -;
flag = i;
}
}
return;
} bool judge(int len) //判断是否可以分为3个回文串
{
int visit1[maxn<<], visit2[maxn<<], cnt1 = , cnt2 = ;
//visit1用来存储所有包含第一个字符的字符串的中点下标
//visit2用来存储包含最后一个字符串的中点下标 for(int i=; i<len; ++i) //遍历一遍,找到存入visit数组中
{//因为以 i 为中点的回文串的长度是s_len[i]-1,所以还要判断一下这个回文串长度是否为 0;
if(i - s_len[i] + == && s_len[i] - > )
visit1[cnt1++] = i;
if(i + s_len[i] - == len- && s_len[i] - > )
visit2[cnt2++] = i;
}
bool flag = false;
int mid;
for(int i=; i<cnt1; ++i) //for循环的嵌套用来让三段中,第一段和第三段两两配对
{
for(int j=cnt2-; j>=; --j)
{
if(visit1[i] + s_len[visit1[i]] - < visit2[j] - s_len[visit2[j]] + )
//选出的两段不能有重合,有重合表示中间没字符了
{
mid = ( (visit1[i] + s_len[visit1[i]] - ) + (visit2[j] - s_len[visit2[j]] + ) ) / ;
//然后取两段中间剩余字符的中点
if(mid - s_len[mid] + <= visit1[i] + s_len[visit1[i]] && s_len[mid]- > )
//判断以中点为中心的回文串是否完全覆盖了中间所有的字符
{
flag = true; //若覆盖了,则表示可以分成三段回文串
break; //就不需要再继续查找了
}
}
}
if(flag) break;
}
return flag;
} int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%s",a);
int len = Init();
manacher(len); bool T_or_F = judge(len);
if(T_or_F)
cout<<"Yes\n";
else
cout<<"No\n";
}
return ;
}
hdu5340—Three Palindromes—(Manacher算法)——回文子串的更多相关文章
- zoj 2744 Palindromes(计算回文子串个数的优化策略)
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2744 题目描述: A regular palindrome i ...
- cf#516C. Oh Those Palindromes(最多回文子串的字符串排列方式,字典序)
http://codeforces.com/contest/1064/problem/C 题意:给出一个字符串,要求重新排列这个字符串,是他的回文子串数量最多并输出这个字符串. 题解:字典序排列的字符 ...
- manacher算法——回文串计算的高效算法
manacher算法的由来不再赘述,自行百度QWQ... 进入正题,manacher算法是一个高效的计算回文串的算法,回文串如果不知道可以给出一个例子:" noon ",这样应该就 ...
- 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- 1089 最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa ...
- 51nod1089(最长回文子串之manacher算法)
题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...
- 求最长回文子串:Manacher算法
主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...
- Manacher's algorithm: 最长回文子串算法
Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abcc ...
- 【转】最长回文子串的O(n)的Manacher算法
Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...
随机推荐
- 嵌入式linux开发:杂七杂八的话
1. 编译器:常用的有Sourcery,linaro等.当然芯片厂家一般也会提供可用的编译器. 2. 将配置和编译时的输出O到其他位置:make O=some_dir 这样做的好处是保持源代码树的干净 ...
- C# 基础备忘录
1. decimal 类型调用ToString()方法后没把末尾的0去掉的解决办法: 例子:decimal? money = Convert.ToDecimal(10.8950); string mo ...
- ckplayer的Error #2033:Can not call javascript:ckstyle()解决
在我们添加多个视频的时候,就会出现这个报错:Error #2033:Can not call javascript:ckstyle(); 但是也不是所有的浏览器都不能正常运行,我这边就是IE10不能正 ...
- 使用Java配置SpringMVC
在此之前,一直使用的是XML的方式配置SpringMVC,现在为了适应Servlert3.0以及JavaConfig的Spring配置方式,在这里记录一下使用Java代码配置SpringMVC.首先, ...
- PyQt5系列教程(四)信号和槽
软硬件环境 OS X EI Capitan Python 3.5.1 PyQt 5.5.1 前言 信号(Signal)和槽(Slot)是Qt编程中对象间通讯的机制.在Qt中,每一个QObject对象, ...
- shell脚本实现tomcat进程—查、杀、启
#!/bin/bash#获取XXX项目进程IDXXXpid=`ps -ef | grep XXX | grep -v grep | awk '{print $2}'` echo "XXX项目 ...
- C# 中带有中国农历的日期选择控件
开源一款自己刚开始接触 C# 时开发的带有农历信息的日期选择控件,记得那时还是在2010年的寒假期间做的这个东西.刚开始接触 C# 时,使用WinForm来开发桌面程序,觉得简直是简单又迅速,由于 C ...
- Spring Boot实践——统一异常处理
注解说明 @ControllerAdvice,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@ControllerAdvice的实现: /** * Special ...
- redis一主二从三哨兵
redis做集群的时候有很多种配置方法,一主二从三哨兵这种模式是官网推荐的.,写配置文件链接的时候,写的是哨兵地址,不是IP,用户名,密码之类的. 一主二从很好理解,一个主的redis,实时备份到两个 ...
- 实现socketChannel 通信例子
https://blog.csdn.net/qq_33935895/article/details/79678345