码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5371

时间:2015-08-12 11:38:09      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:hdu5371 manacher算法

题意:找三个连续子序列a b c,满足a b对称且b c对称

思路:先求出序列中以每个位置为中心的回文串长度存在p[i]数组里,用manacher算法,O(n)的时间,然后遍历p数组,如果在当前位置的回文串范围内,与之后的位置上的回文串范围能覆盖彼此任意一个的至少一半,就说明满足条件,依此找出最优解

还在wa的同学可以试试我代码下面的数据

代码:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define sss(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a) memset(a,0,sizeof(a))
#define ss(a,b) scanf("%d%d",&a,&b)
#define s(a) scanf("%d",&a)
#define p(a) printf("%d\n", a)
#define INF 0x3f3f3f3f
#define w(a) while(a)
#define PI acos(-1.0)
#define LL long long
#define eps 10E-9
#define N 1000000+20
#define mod 1000000007
#define _min(x, y) ((x)<(y)?(x):(y))
using namespace std;
void mys(int& res)
{
    int flag=0;
    char ch;
    while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-'))
        if(ch==EOF)  res=INF;
    if(ch=='-')  flag=1;
    else if(ch>='0'&&ch<='9')  res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')  res=res*10+ch-'0';
    res=flag?-res:res;
}
void myp(int a)
{
    if(a>9)
        myp(a/10);
    putchar(a%10+'0');
}
/*************************THE END OF TEMPLATE************************/
int n, p[N];
int s[N];
int str[N];
void kp()
{
    int i;
    int mx = 0;
    int id;
 //   for(i=n; str[i]!=0; i++)
 //       str[i] = 0;
    for(i=1; i<n; i++)
    {
        if( mx > i )
            p[i] = _min( p[2*id-i], p[id]+id-i );
        else
            p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
            ;
        if( p[i] + i > mx )
        {
            mx = p[i] + i;
            id = i;
        }
    }
}
void init()
{
    int i, j, k;
    str[0] = -1;
    str[1] = -2;
    for(i=0; i<n; i++)
    {
        str[i*2+2] = s[i];
        str[i*2+3] = -2;
    }
    n = n*2+2;
    s[n] = 0;
}
int main()
{
    int t;
    int time=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)  s(s[i]);
        init();//manacher模板
        kp();//manacher模板
        int top = 0;
        for(int i=1; i<n; i+=2){//枚举加优化
              if((p[i]-1)>1 && !((p[i]-1)%2)){//回文串长度必然要大于一并且为偶数
                    for(int j=p[i]-1; j>top; j-=2){//当目前解小于top时就没必要进行了,继续走会超时
                         if(p[j+i]-1 >= j) {
                                top = (j);
                                break;
                         }
                    }
              }
        }
        printf("Case #%d: ",time++);
        printf("%d\n",top/2*3);
    }
    return 0;
}
/*
1
13
1 2 2 1 1 2 3 3 2 1 1 2 3

1
11
1 1 2 1 1 2 1 1 2 1 1
*/



版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu5371

标签:hdu5371 manacher算法

原文地址:http://blog.csdn.net/bigsungod/article/details/47440657

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