题目链接: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