[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
");
 72             continue;
 73         }
 74         if(len == 3) {
 75             printf("Yes
");
 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("
");
 84         // for(int i = 0; i < len; i++) {
 85         //     printf("%c ", tmp[i]);
 86         // }
 87         // printf("
");
 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
", i);
 95             }
 96             if(i + pre[i] == len) {
 97                 tail[t++] = i;
 98                 // printf("tail i = %d
", 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
");
122         }
123         else {
124             printf("No
");
125         }
126     }
127 }
原文地址:https://www.cnblogs.com/kirai/p/4789588.html