HDU 5340——Three Palindromes——————【manacher处理回文串】

Three Palindromes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1244    Accepted Submission(s): 415

Problem Description

Can we divided a given string S into three nonempty palindromes?

Input

First line contains a single integer T≤20 which denotes the number of test cases.

For each test case , there is an single line contains a string S which only consist of lowercase English letters.1≤|s|≤20000

Output

For each case, output the "Yes" or "No" in a single line.

Sample Input

2
abc
abaadada

Sample Output

Yes
No

题目大意:问是否可以找出三段回文串。

题解:

没有进行暴力压位,时间接近超时。但是很侥幸过了。

#include<bits/stdc++.h>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=20200;
int pre[maxn*2],suf[maxn*2];
int p[maxn*2];
char str[maxn],trans[maxn*2];
int Transform(){
  //  memset(p,0,sizeof(p));
    memset(pre,0,sizeof(pre));
    memset(suf,0,sizeof(suf));
    int len=strlen(str);
    trans[0]=‘$‘;
    for(int i=1;i<=2*len;i+=2){
        trans[i]=‘#‘;
        trans[i+1]=str[i/2];
    }
    trans[2*len+1]=‘#‘;
    trans[2*len+2]=‘@‘;
    return 2*len+1;
}
int manacher(){
    int len=Transform();
    int mx=0,pos=0;
    for(int i=1;i<=len;i++){
        if(i<mx){
            p[i]=min(p[2*pos-i],mx-i);
        }else{
            p[i]=1;
        }
        for(;trans[i+p[i]]==trans[i-p[i]];p[i]++);
        if(mx<i+p[i]){
            mx=i+p[i];
            pos=i;
        }
    }
    return len;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s",str);
        int lens=strlen(str);
        if(lens<3){
            printf("No\n");continue;
        }else if(lens==3){
            printf("Yes\n");continue;
        }else{
            int len= manacher();
            for(int i=2;i<len;i++){
                if(p[i]==i){
                    pre[i+p[i]-1]=1;
                }
                if(p[i]==len-i+1){
                    suf[i-p[i]+1]=1;
                }
            }
            int flag=0;
            for(int i=2;i<len&&(!flag);i++){
                for(int j=1;j<p[i]&&(!flag);j++){
                    if(pre[i-j]&suf[i+j]){
                        flag=1;
                        printf("Yes\n");
                    }
                }
            }
            if(!flag){
                printf("No\n");
            }
        }
    }
    return 0;
}

  

时间: 2024-10-18 11:30:15

HDU 5340——Three Palindromes——————【manacher处理回文串】的相关文章

HDU 5371 Hotaru&#39;s problem (Manacher,回文串)

题意:给一个序列,找出1个连续子序列,将其平分成前,中,后等长的3段子序列,要求[前]和[中]是回文,[中]和[后]是回文.求3段最长为多少?由于平分的关系,所以答案应该是3的倍数. 思路:先Manacher求最长子串,利用期间所记录的P 数组,穷举一下所有可能的前两串,再用O(1)时间判断第3串是否符合要求. 具体做法: (1)P[i]记录的是以i为中心,从i-P[i]+1到i+P[i]-1这段都是回文.由于前两段之和必为偶数,所以必须选取str[i]为'#'的. (2)扫一遍每个'#',以其

HDU 5371(Hotaru&#39;s problem-2次回文串)

Hotaru's problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2432    Accepted Submission(s): 841 Problem Description Hotaru Ichijou recently is addicated to math problems. Now she is playin

hdu 3294 manacher 求回文串

感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位置i的答案时,利用已经算出的1~i-1位置的答案. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define maxn 222222 5 using namespace std; 6 7

Codeforces Round #427 (Div. 2) D. Palindromic characteristics(Manacher求回文串)

题目链接:Codeforces Round #427 (Div. 2) D. Palindromic characteristics 题意: 给你一个串,定义k-th回文串,让你求每个k-th的数量. 题解: manacher处理好后做一下dp就行了. 当然也可以直接dp不用manacher. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 cons

Manacher 入门+模板 回文串专用算法

Manacher 算法 回文串专用算法 manacher 人名,该算法的发明者.palindrome名词:回文. 博客推荐 https://www.cnblogs.com/lykkk/p/10460087.html,比较简洁,代码清晰. https://www.cnblogs.com/cloudplankroader/p/10988844.html, 一些细节的东西比较讲解比较细. 模板 //预处理函数,使得处理后的字符串长度为奇数,并且有一些比较好的性质 int init(char* s, c

【BZOJ 3676】 [Apio2014]回文串

3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 646 Solved: 219 [Submit][Status][Discuss] Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的"出 现值"为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行,为一个只包含小写字母(a -z)的非空字符串s. Output 输出

Hdu 5340 Three Palindromes 最大回文串 Manacher

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 80    Accepted Submission(s): 21 Problem Description Can we divided a given string S into three nonempty palindromes? Input Fir

hdu 5340 Three Palindromes(字符串处理+ 回文)

hdu 5340 Three Palindromes 问题描述 判断是否能将字符串S分成三段非空回文串. 输入描述 第一行一个整数T,表示数据组数.T \leq 20T≤20 对于每一个组,仅包含一个由小写字母组成的串.1 \leq |S| \leq 200001≤∣S∣≤20000 输出描述 对于每一组,单行输出"Yes" 或 "No". 输入样例 2 abc abaadada 输出样例 Yes No 题目大意:给出一个字符串,判断,是否能将其分成三个不为空的回文

hdu 5340 Three Palindromes 【Manacher】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5340 题意:判断一个字符串能否分为三个回文串 解法:manacher枚举第一第三个,判断第二个. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #inclu