码迷,mamicode.com
首页 > Windows程序 > 详细

Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化

时间:2016-08-20 00:16:51      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

Ural Federal University Contest, SKB Kontur Cup
Petrozavodsk Winter Training Camp, Saturday, February 2, 2013


Problem D. Five Palindromes
Input file: input.txt
Output file: output.txt
Time limit: 2 seconds (3 seconds for Java)
Memory limit: 256 mebibytes


Your task is to divide a string into five non-empty palindromes.
Input
The input contains one string consisting of n lowercase English letters (5 6 n 6 105).
Output
Output “NO” if such division is impossible. Otherwise, output “YES” on the first line, and the next five
lines should contain one palindrome each, which, if concatenated in this order, form the given string.
Examples
input.txt                                   output.txt
aaabbcdcaa                          YES
                                                 aa
                                                 a
                                                 bb
                                                 cdc
                                                 aa
spaaaaaaarta                       NO
abacdcxyxzpz                         NO


Source

Petrozavodsk Winter-2013. Ural FU Contest


My Solution

 manacher、一个串切割成5个回文子串、优化

第一次使用manacher 嘿嘿??

为了方便处理奇偶的情况, 我们把 区间 [ i , j ] 的回文子串半径保存在 len[ i + j ] 里, 

if(len[ i + j ] >= (j - i)/2 + 1) 则[ i , j ] 为回文串

可以O(n)的处理出len 所有中心的回文子串长度


这里先跑一边 manacher(n) 得到 len[]数组

然后O(n) 的预处理出 第一个字符串的右端点 i,放在一个队列里

并且O(n) 的预处理出 最后一个字符串的左端点 j,放在一个vector里

对于每一个 i, 把所有 (i < j)的j跑一遍

并且判断[ i+1, j -1 ] 是否有回文子串 [ i + 1, k ],  [ k + 1, u ],  [ u + 1, j - 1 ] 如果满足条件则输出并且用 return 0; 或者 exit(0)直接结束程序

否则跑完所有情况都没有符合要求的答案则 "NO"


复杂度 不知道怎么算 大概 nlogn的, 如果不预处理出那些东西最糟糕的复杂度可能 O(n^2) TLE 23,预处理后大概最好的情况 O(n), 最差的情况O(nlogn)左右


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

int len[2*maxn];
char str[maxn];

inline void manacher(int n)
{
    int p, q, r;
    len[0] = 1;
    for(int i = 1, j = 0; i < (n << 1) - 1; i++){
        p = i >> 1, q = i - p, r = ((j + 1) >> 1) + len[j] - 1;
        len[i] = r < q ? 0 : min(r - q + 1, len[(j << 1) - i]);
        while(p > len[i] - 1 && q + len[i] < n && str[p - len[i]]
              == str[q + len[i]])
                len[i]++;
        if(q + len[i] - 1 > r)
            j = i;
    }
}

queue<int> que;
vector<int> vec;


int main()
{

    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #ifdef LOCAL
    int T = 3;
    while(T--){
    #endif // LOCAL
    scanf("%s", str);
    int n = strlen(str);
    manacher(n);
    //for(int i = 0; i < 2*n; i++)
    //cout<<str<<endl;
    for(int i = 0; i < n; i++){
        if(i == 0 || len[0 + i] >= (i - 0) / 2 + 1){que.push(i);}
    }
    for(int i = n-1; i >= 0; i--){
        if(i == n - 1 || len[n - 1 + i] >= (n - 1 - i) / 2 + 1){vec.push_back(i);}
    }

    int szv = vec.size(), i, j;

    while(!que.empty()){
        i = que.front();
        que.pop();
        for(int x = 0; x < szv; x++){
            j = vec[x];
            if(j <= i) break;
    //!
            for(int k = i + 1; k < j; k++){
                if(k == i + 1 || len[i + 1 + k] >= (k - (i+1)) / 2 + 1){
                    for(int u = k + 1; u < n; u++){
                        if(u == k + 1 || len[k + 1 + u] >= (u - (k+1)) / 2 + 1){
                            if(len[u + 1 + j - 1] >= (j - 1 - (u + 1)) / 2 + 1){
                                printf("YES\n");
                                for(int v = 0; v < n; v++){
                                    putchar(str[v]);
                                    if(v == i || v == j-1 || v == k || v == u) putchar('\n');
                                }
                                putchar('\n');
                                return 0;
                            }
                        }
                        //else break;
                    }
                }
                //else break;
            }

        }
        //else break;

    }
    printf("NO\n");

    #ifdef LOCAL
    vec.clear();
    printf("\n");
    }
    #endif // LOCAL
    return 0;
}

  Thank you!

                                                                                                                                               ------from ProLights

Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化

标签:

原文地址:http://blog.csdn.net/prolightsfxjh/article/details/52254805

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!