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>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <assert.h>

using namespace std;

int t;
int p[220100];
char s[220100], c[221000];
int pre[221000], last[221000];

int solve()
{
    int len = strlen(s);
    c[0] = ‘$‘;
    for (int i = 0; i<len; i++)
        c[i * 2 + 1] = ‘#‘, c[i * 2 + 2] = s[i];
    c[len * 2 + 1] = ‘#‘;
    len = len * 2 + 2;
    c[len] = 0;
    int mx = 0, id = 0;
    for (int i = 1; i<len; i++)
    {
        if (mx>i) p[i] = min(p[id * 2 - i], p[id] + id - i);
        else p[i] = 1;
        while (c[i + p[i]] == c[i - p[i]]) p[i]++;
        if (i + p[i]>mx) mx = i + p[i], id = i;
    }

    int p_num = 0, l_num = 0;
    for (int i = 2; i < len - 1; i++)
    {
        if (i == p[i]) pre[p_num++] = i;
        if (i + p[i] == len) last[l_num++] = i;
    }

    for (int i = 0; i < p_num; i++)
    {
        for (int j = l_num - 1; j >= 0; j--)
        {
            int pos1 = pre[i] + p[pre[i]];
            int pos2 = last[j] - p[last[j]];
            if (pos1 > pos2) break;
            int mid = (pos1 + pos2) / 2;
            if (mid<=len-4)
            if (mid - pos1 + 1  <= p[mid]) return 1;
        }
    }
    return 0;
}

int main()
{
    scanf("%d", &t);
    while (t--)
    {
        scanf("%s", s);
        if (solve()) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

版权声明:转载请注明出处。

时间: 2024-08-11 05:43:20

hdu 5340 Three Palindromes 【Manacher】的相关文章

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

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)

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

hdu 5371 Hotaru&#39;s problem【manacher】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意: 给出一个长度为n的串,要求找出一条最长连续子串.这个子串要满足:1:可以平均分成三段,2:第一段和第三段相等,3:第一段和第二段回文.求最大子串的长度. 代码: #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h&

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 4970 Killing Monsters 【搜索】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4970 题目大意:给你一些防御塔的位置和其攻击力,以及一些怪物的血量和位置,问走到终点还有几个怪物活着. 题目思路:最开始看题目的时候就是区间更新的过程觉得会花很多时间,然后用的树状数组,后来发现用的一个机智方法可以过,简单了很多. 区间更新的主要时间是花在塔的伤害,(L,R)D伤害上面,我们用一个sttack数组记录伤害,在attack[L]+=D,在attack[R]-=D,然后从前往后扫一遍,可

HDU 4941 Magical Forest 【离散化】【map】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 题目大意:给你10^5个点,每个点有一个数值,点的xy坐标是0~10^9,点存在于矩阵中.然后给出10^5个操作,1代表交换行,2代表交换列,3代表查询坐标为xy点的数值. 数据量很大........ 所以一直没有思路 后来赛后看了题解是先用离散化然后存在线性map里面. #include <iostream> #include <cstdio> #include <map

HDU 4937 Lucky Number 【搜索】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4937 题目大意:给你T组数据,每组数据输入一个小于=1e12的数num,如果这个数的n进制下都是由3,4,5,6这四个数字组成的,则说明这个n进制是num的幸运进制,现在求一个num有几个幸运进制,如果有无限多个幸运进制则输出-1. 题解: 如果输入的num转化后是一位数,显然可以得到3,4,5,6这四个数字应该输出-1. 如果输入的num转化后是二位数,以base作为进制的话,转换问base进制就

hdu 4908 BestCoder Sequence【DP】

题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=4908 题目大意:给出一个排列,一个m,求出这个排列的连续子序列中有多少个序列式以m为中位数. 由于是一个排列,不会出现重复的数字,记录一下m的位置index,然后以index为分界线,往左求出s[i](表示从i到index之间有多少大于m),b[i](表示从i到index之间有多少小于m),往右求出s[i](表示从index到i之间有多少大于m),b[i](表示从index到i之间有多少小于m).