HDU 5371 Hotaru's problem

来源:互联网 发布:查明星航班软件 编辑:程序博客网 时间:2024/05/09 02:45

利用Manacher求出每两个数字中间位置的回文长度

之后利用set进行维护,大题思路如下:

要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,比如上边的两个字符串,共享 8 9 10这一部分。 也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样。 因为我们已经记录下来以第i个点和第i+1个点为中心的回文串长度, 那么问题可以转化成,相距x的两个数a[i],a[i+x],满足a[i]/2>=x 并且 a[i+x]/2>=x,要求x尽量大

这可以用一个set维护,一开始集合为空,依次取出a数组中最大的元素,将其下标放入set中,每取出一个元素,再该集合中二分查找比i+a[i]/2小,但最大的元素,更新答案。 然后查找集合中比i-a[i]/2大,但最小的元素,更新答案。

但是据说数据比较水,所以可以用可能退化成O(n2)的枚举方法也可以过。

参考官方题解:http://bestcoder.hdu.edu.cn/blog/

//      whn6325689//      Mr.Phoebe//      http://blog.csdn.net/u013007900#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>#include <functional>#include <numeric>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define eps 1e-9#define PI acos(-1.0)#define INF 0x3f3f3f3f#define LLINF 1LL<<62#define speed std::ios::sync_with_stdio(false);typedef long long ll;typedef unsigned long long ull;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;typedef vector<int> vi;#define CLR(x,y) memset(x,y,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define lowbit(x) (x&(-x))#define MID(x,y) (x+((y-x)>>1))#define ls (idx<<1)#define rs (idx<<1|1)#define lson ls,l,mid#define rson rs,mid+1,r#define root 1,1,ntemplate<class T>inline bool read(T &n){    T x = 0, tmp = 1;    char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MAXN=200010;int num[MAXN],dst[MAXN];int n,len[MAXN];set<int> st;pii pos[MAXN];void Manacher(int *s){    int l=0;    dst[l++]=-2;dst[l++]=-1;    for(int i=0;i<n;i++)    {        dst[l++]=s[i];        dst[l++]=-1;    }    int mx=0,po=0;    for(int i=0;i<l;i++)    {        len[i]=mx>i?min(mx-i,len[2*po-i]):1;        while(dst[i-len[i]]==dst[i+len[i]])            len[i]++;        if(len[i]+i>mx)        {            mx=len[i]+i;            po=i;        }    }}int main(){    freopen("data.txt","r",stdin);    int T,cas=1;    scanf("%d",&T);    while(T--)    {        st.clear();CLR(len,0);        scanf("%d",&n);        for(int i=0;i<n;i++)            scanf("%d",&num[i]);        Manacher(num);        for(int i=0;i<n;i++)        {            pos[i]=mp((len[i*2+1]-1)/2,i);        }        sort(pos,pos+n);        int ans=0;        set<int>::iterator it,it1;        for(int i=n-1;i>=0;i--)        {            st.insert(pos[i].second);            it=(st.lower_bound(pos[i].second-pos[i].first));            it1=(st.upper_bound(pos[i].second+pos[i].first));            it1--;            ans=max(ans,*it1-pos[i].second);            ans=max(ans,pos[i].second-*it);        }        printf("Case #%d: %d\n",cas++,3*ans);    }    return 0;}

枚举法

//      whn6325689//      Mr.Phoebe//      http://blog.csdn.net/u013007900#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>#include <functional>#include <numeric>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define eps 1e-9#define PI acos(-1.0)#define INF 0x3f3f3f3f#define LLINF 1LL<<62#define speed std::ios::sync_with_stdio(false);typedef long long ll;typedef unsigned long long ull;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;typedef vector<int> vi;#define CLR(x,y) memset(x,y,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define lowbit(x) (x&(-x))#define MID(x,y) (x+((y-x)>>1))#define ls (idx<<1)#define rs (idx<<1|1)#define lson ls,l,mid#define rson rs,mid+1,r#define root 1,1,ntemplate<class T>inline bool read(T &n){    T x = 0, tmp = 1;    char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MAXN=100007;int num[MAXN<<1];int tmp[MAXN<<1];int len[MAXN<<1];int n;void manacher(int *st,int *dst){    int l=0;    dst[l++]=-2;dst[l++]=-1;    for(int i=0;i<n;i++)    {        dst[l++]=st[i];        dst[l++]=-1;    }    int mx=0,po=0;    for(int i=0;i<l;i++)    {        len[i]=mx>i?min(mx-i,len[2*po-i]):1;        while(dst[i-len[i]]==dst[i+len[i]])            len[i]++;        if(len[i]+i>mx)        {            mx=len[i]+i;            po=i;        }    }}int main (){    freopen("data.txt","r",stdin);    int T,cas=1;    read(T);    while(T--)    {        read(n);        for(int i=0;i<n;i++)            read(num[i]);        manacher(num,tmp);        int ans=0,l=2*n+1;        for(int i=1;i<=l;i+=2)            for(int j=i+len[i]-1;j-i>ans;j-=2)                if(j-i+1<=len[j])                {                    ans=j-i;                    break;                }        ans=ans/2*3;        printf("Case #%d: %d\n",cas++,ans);    }    return 0;}
0 0
原创粉丝点击