HDU 5340 Three Palindromes

Three Palindromes

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2185 Accepted Submission(s): 787

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 consist of lowercase English letters.1≤|s|≤20000

Output

For each case, output the “Yes” or “No” in a single line.

Sample Input

2
abc
abaadada

Sample Output

Yes
No

思路:

给你一个字符串,把这个字符串分成3份,每份都是一个回文串。

思路:

先用回文自动机把所有的字母代表的最大回文串计算出来,如果这些串超过3个,那么就不可能分成3份,如果字符串的长度大于等于3且只有一个最大回文串,那么就一定可以,因为可以把最右边一个和最左边一个分开,这样就有三份了,如果有两份的话,那么就看看能不能把其中一份分开,比如aa或者aaa这类的才可以其他的左右中心对称,无法分开。

#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 2e+4 + 10;
int len[maxn], fail[maxn], ch[maxn][26], ans[maxn];
char s[maxn];
int getfail(int n, int x) {
    while (s[n - len[x] - 1] != s[n]) x = fail[x];
    return x;
}
int main() {
    int t;
    scanf("%d", &t);
    getchar();
    while (t--) {
        memset(len , 0, sizeof(len));
        memset(fail, 0, sizeof(fail));
        memset(ch , 0, sizeof(ch));
        memset(ans ,0,sizeof(ans));
        scanf("%s", s + 1);
        int le = strlen(s + 1), cnt = 1, cur = 0;
        if (le < 3) {
            printf("No\n");
            continue;
        }
        len[1] = -1, fail[0] = 1;
        for (int i = 1; i <= le; i++) {
            int now = s[i] - 'a';
            cur = getfail(i, cur);
            ans[i] = len[cur] + 2;
            if (!ch[cur][now]) {
                len[++cnt] = len[cur] + 2;
                fail[cnt] = ch[getfail(i, fail[cur])][now];
                ch[cur][now] = cnt;
            }
            cur = ch[cur][now];
        }
        int Min = 0, cntt = 0;
        for (int i = le; i >= 1; i--) {
            if (ans[i] > 1) {
                if (ans[i] - ans[i - 1] == 1&& i > 1) cntt++;
                i -= ans[i] - 1;
            }
            Min++;
        }
        if (Min == 3 || Min == 1) printf("Yes\n");
        else if (Min == 2 && cntt) printf("Yes\n");
        else  printf("No\n");
    }
    return 0;
}

你可能感兴趣的:(HDU)