[HDOJ5340]Three Palindromes

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5340

看看是否可以将一个字符串拆成三个回文字串。

首先可以肯定的是,如果字符串长度<3是一定不存在的,=3是一定存在的。接下来讨论>3的情况

先用manacher处理一下字符串得到pre数组。数组的含义是以当前位置为中心的回文串的半径。

可以先分别从头到尾记下回文串的情况,接着看看是否可以将中间的拼凑成一个回文串。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19
 20 using namespace std;
 21
 22 const int maxn = 20010;
 23 char s[maxn];
 24 int pre[maxn<<1];
 25 char tmp[maxn<<1];
 26 int head[maxn<<1];
 27 int tail[maxn<<1];
 28
 29 inline int max(int x, int y) {
 30     return x > y ? x : y;
 31 }
 32
 33 int init(char *tmp, char *str) {
 34     int len = strlen(str);
 35     tmp[0] = ‘$‘;
 36     for(int i = 0; i <= len; i++) {
 37         tmp[2*i+1] = ‘#‘;
 38         tmp[2*i+2] = str[i];
 39     }
 40     len = 2 * len + 2;
 41     tmp[len] = 0;
 42     return len;
 43 }
 44
 45 void manacher(int *pre, char *tmp, int len) {
 46     int id = 0;
 47     int mx = 0;
 48     for(int i = 1; i < len; i++) {
 49         pre[i] = mx > i ? min(pre[2*id-i], mx-i) : 1;
 50         while(tmp[i+pre[i]] == tmp[i-pre[i]]) {
 51             pre[i]++;
 52         }
 53         if(pre[i] + i > mx) {
 54             id = i;
 55             mx = pre[i] + id;
 56         }
 57     }
 58 }
 59
 60 int len;
 61 int main() {
 62     // freopen("in", "r", stdin);
 63     int T;
 64     scanf("%d", &T);
 65     while(T--) {
 66         memset(head, 0, sizeof(head));
 67         memset(tail, 0, sizeof(tail));
 68         scanf("%s", s);
 69         len = strlen(s);
 70         if(len < 3) {
 71             printf("No\n");
 72             continue;
 73         }
 74         if(len == 3) {
 75             printf("Yes\n");
 76             continue;
 77         }
 78         len = init(tmp, s);
 79         manacher(pre, tmp, len);
 80         // for(int i = 0; i < len; i++) {
 81         //     printf("%d ", pre[i]);
 82         // }
 83         // printf("\n");
 84         // for(int i = 0; i < len; i++) {
 85         //     printf("%c ", tmp[i]);
 86         // }
 87         // printf("\n");
 88         int flag = 0;
 89         int h = 0;
 90         int t = 0;
 91         for(int i = 2; i < len - 1; i++) {
 92             if(i == pre[i]) {
 93                 head[h++] = i;
 94                 // printf("head i = %d\n", i);
 95             }
 96             if(i + pre[i] == len) {
 97                 tail[t++] = i;
 98                 // printf("tail i = %d\n", i);
 99             }
100         }
101         for(int i = 0; i < h; i++) {
102             for(int j = t - 1; j >= 0; j--) {
103                 int ll = head[i] + pre[head[i]];
104                 int rr = tail[j] - pre[tail[j]];
105                 if(ll > rr) {
106                     break;
107                 }
108                 int mm = (ll + rr) >> 1;
109                 if(pre[mm] - 1 >= mm - ll) {
110                     flag = 1;
111                 }
112                 if(flag) {
113                     break;
114                 }
115             }
116             if(flag) {
117                 break;
118             }
119         }
120         if(flag) {
121             printf("Yes\n");
122         }
123         else {
124             printf("No\n");
125         }
126     }
127 }
时间: 2024-10-22 11:24:12

[HDOJ5340]Three Palindromes的相关文章

[UVa] Palindromes(401)

UVA - 401 Palindromes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDED

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <

Codeforces Round #316 (Div. 2)E. Pig and Palindromes DP

E. Pig and Palindromes Peppa the Pig was walking and walked into the forest. What a strange coincidence! The forest has the shape of a rectangle, consisting of n rows and m columns. We enumerate the rows of the rectangle from top to bottom with numbe

Codeforces #316 E Pig and Palindromes DP

// Codeforces #316 E Pig and Palindromes // // 题目大意: // // 给你一张地图,n*m每个点是一个字母,现在从(0,0)出发, // 每次只能往右或者往下走,求走到(n-1,m-1)形成回文串的方法数. // // 解题思路: // // 动态规划.首先.如果起点和终点的字母不相同,那么肯定 // 不能形成回文串,直接输出0.对于能形成回文串.我们设状态 // d(step,i,j)表示走了step步,从第0行走到i行,第n-1行走到j行的 /

UVA11584---Partitioning by Palindromes(dp)

We say a sequence of characters is a palindrome if it is the same written forwards and backwards. For exam- ple, ' racecar ' is a palindrome, but ' fastcar ' is not. A partition of a sequence of char- acters is a list of one or more disjoint non-empt

UVa 401 Palindromes(字符串,回文)

 Palindromes  A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string i

UVA 之401 - Palindromes

A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string is read from ri

1167: 零起点学算法74——Palindromes _easy version

1167: 零起点学算法74--Palindromes _easy version Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 1754  Accepted: 1023[Submit][Status][Web Board] Description "回文串"是一个正读和反读都一样的字符串,比如"level"或者"noon"等等就是回文串.请写一个

洛谷P1207 [USACO1.2]双重回文数 Dual Palindromes

P1207 [USACO1.2]双重回文数 Dual Palindromes 291通过 462提交 题目提供者该用户不存在 标签USACO 难度普及- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做“回文数”.例如,12321就是一个回文数,而77778就不是.当然,回文数的首和尾都应是非零的,因此0220就不是回文数. 事实上,有一些数(如21),在十进制时不是回文数,但在其它进制(如二进制时为10101)时就是回文数. 编