hdu 5340 Three Palindromes

  前几晚 BC 的第二题,官方给出的题解是:

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

  代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = 20003;
 6
 7 char s[N], s2[N << 1];
 8 int p[N << 1];
 9 bool pre[N], suf[N];
10
11 int main() {
12     int t;
13     scanf("%d",&t);
14     while(t--) {
15         scanf("%s",s);
16         int n = strlen(s);
17         s2[0] = ‘$‘;
18         s2[1] = ‘#‘;
19         for(int i = 0; i < n; ++i) {
20             s2[(i << 1) + 2] = s[i];
21             s2[(i << 1) + 3] = ‘#‘;
22         }
23         n = (n << 1) + 2;
24         s2[n] = ‘\0‘;
25         int right = 0, id = 0;
26         p[0] = 0;
27         for(int i = 1; i < n; ++i) {
28             if(right > i)
29                 p[i] = min(p[(id << 1) - i], right - i);
30             else    p[i] = 0;
31             while(s2[i + p[i] + 1] == s2[i - p[i] - 1])    ++p[i];
32             if(i + p[i] > right) {
33                 right = i + p[i];
34                 id = i;
35             }
36         }
37
38         int slen = (n >> 1) - 1;
39
40         for(int i = 0; i < slen; ++i) {
41             int s2id = i + 2;
42             pre[i] = (s2id - p[s2id] == 1);
43         }
44         for(int i = slen - 1; i >= 0; --i) {
45             int s2id = i + slen + 1;
46             suf[i] = (s2id + p[s2id] == n - 1);
47         }
48
49         bool flag = 0;
50         for(int i = 4; i <= n - 4; ++i) {
51             int j = s2[i] == ‘#‘ ? 2 : 1;
52             for(; j <= p[i]; j += 2) {
53                 int id1 = i - j - 1;
54                 int id2 = i + j + 1;
55                 if(pre[(id1 >> 1) - 1] && suf[(id2 >> 1) - 1]) {
56                     flag = 1;
57                     break;
58                 }
59             }
60             if(flag)    break;
61         }
62         puts(flag ? "Yes": "No");
63     }
64     return 0;
65 }

时间: 2024-11-06 16:03:38

hdu 5340 Three Palindromes的相关文章

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

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

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

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 5340 最长回文子串变形

http://acm.hdu.edu.cn/showproblem.php?pid=5340 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

hdu 5340 Manachers + 枚举

题意:给你一个字符串问能否拆分为三个回文字符串?能就输出yes,否则输出no. 知识补充: 最长回文子串算法(Manacher算法): 求解最长回文子串的线性时间复杂度算法,主要是通过中心扩展的方法极大地避免了重复计算.实现如下: 为了避免对字符串奇偶数的讨论,先对字符串做预处理如下: 规则为在字符间和两边插入'#'字符,为了避免越界处理,最两边插入'^'和'$'字符. 原本字符串为:asd 预处理后为:^#a#s#d#$ 然后实现部分:设置两个变量:c 和 r,表示当前最长回文字符串的中心和边