HDU 5340-Three Palindromes(Manacher算法)

题目地址:HDU 5340

题意:问是否能将字符串str分解为三段非空的回文串。

思路:我们根据Manacher算法对字符串进行处理,处理过程中产生的P数组,我们可以得到两个数组first和last。

first存储的是第一个回文串的半径可能值。

last存储的是第三个回文串的半径可能值。

根据first和last我们可以枚举第一个回文串和第三个回文串,然后根据半径找出第二个回文串的初始位置和结束位置。然后计算出第二个回文串的中点:

1.如果ll>rr,则第二个字符串的长度为负数,pass

2.如果p[mid]=1,说明第二个回文串为”#”,相当于空,pass

3.如果三个子字符串的长度加起来大于len,证明符合长度,跳出来即可。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
const int maxn=110010;
char str[maxn];
char s[maxn*2];
int p[maxn*2];
int len;
int first[maxn*2];
int last[maxn*2];
void Manacher()
{
    int i;
    s[0]=‘$‘;
    s[1]=‘#‘;
    for(i=0;i<len;i++) {
        s[i*2+2]=str[i];
        s[i*2+3]=‘#‘;
    }
    s[i*2+2]=‘\0‘;
    len=2*i+2;
    int MaxL,id;
    id=MaxL=0;
    memset(p,0,sizeof(p));
    for(int i=0; i<len; i++) {
        if(p[id]+id>i)
            p[i]=min(p[2*id-i],p[id]+id-i);
        else
            p[i]=1;
        while(s[i+p[i]]==s[i-p[i]])
            p[i]++;
        if(p[i]+i>p[id]+id) {
            id=i;
        }
        if(p[i]>MaxL)
            MaxL=p[i];
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s",&str);
        len=strlen(str);
        Manacher();
        int l1=0,r1=0;
        for(int i=2;i<=len-2;i++){
            if(i==p[i])
                first[l1++]=i;
            if(p[i]==len-i)
                last[r1++]=i;
        }
        int flag=0;
        int ll,rr,mid;
        for(int i=0;i<l1;i++){
            for(int j=0;j<r1;j++){
                ll=first[i]+p[first[i]];
                rr=last[j]-p[last[j]];
                if(ll>rr)
                    continue;
                mid=(ll+rr)/2;
                if(ll==rr&&s[mid]==‘#‘)
                    continue;
                if(p[first[i]]*2-1+p[mid]*2-1+p[last[j]]*2-1>=len+1){
                    flag=1;
                    break;
                }
            }
            if(flag)
                break;
        }
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 02:49:17

HDU 5340-Three Palindromes(Manacher算法)的相关文章

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 3294 Girls&#39; research (Manacher算法 + 记录区间)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294 题目大意:输入一个字符ch和一个字符串,问如果把ch当作'a'的话,字符串的每个字符也要做相应变化,如b aa,若b为'a',则b前面的a就为'a'前面的'z',这里是循环表示,输出字符串的最长回文子串,如果最长回文子串串长为1,输出No solution! 几乎是模板题,唯一的特别之处就是要输出回文串字符,所以要记录max(Mp[i])对应的在原串中的字符区间,根据Manacher算法的步骤

HDU 3616 Best Reward (Manacher算法 前缀回文+后缀回文)

Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 785    Accepted Submission(s): 338 Problem Description After an uphill battle, General Li won a great victory. Now the head of state

hdu 5340 Three Palindromes

前几晚 BC 的第二题,官方给出的题解是: 然后我结合昨天刚看的 Manacher 算法试着写了下,发现 pre.suf 数组挺难构造的,调试了好久,然后就对中间进行枚举了,复杂度应该是 O(n2) 吧,我第一次交时超时了,以为真的要用什么暴力压位,可是我还不会啊,然后作了一些少许的优化提交本想再 T 一次的,没想到竟然神奇的过了,900+ms 水过,原来还是能卡过的……于是我把更多的细节进行优化,把 *2 和 /2 操作都改为移位运算,再提交时就下降到了 700+ms  :-D 代码如下: 1

HDU - 5340 Three Palindromes(manacher算法)

http://acm.hdu.edu.cn/showproblem.php?pid=5340 题意 判断是否能将字符串S分成三段非空回文串 分析 manacher预处理出前缀和后缀回文的位置, 枚举第一个回文串和第三个回文串,这样得到第二个回文串的区间,找中点,因为manacher处理后所有的回文串长度都是奇数,然后根据中点的回文半径判断中间部分是否回文即可, 复杂度o(n2).至于n2复杂度为什么能水过去..不是很懂 #include<iostream> #include<cmath&

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

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( 折半枚举+Manacher+记录区间 )

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

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 F