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

bc#32-2 Positive and Negative

时间:2015-03-09 06:59:29      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=570

给定一个数组(a0,a1,a2,?an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP−sum(i,j) 刚好为K。这里NP−sum(i,j)=ai−ai+1+ai+2+?+(−1)^(j−i)*aj。

分基数和偶数讨论

开始用set做tle

后来改成哈希表+输入优化就好多了

线性探测和二次探测都大约800ms

线性探测法:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define mo 1000007
int a[1000010];
ll sum[1000010];
int n,k;
ll v[1000010];
int n1[1000010],h[mo],ee;
void ins(ll k)
{
    int p=abs(k)%mo;
    v[ee]=k;
    n1[ee]=h[p];
    h[p]=ee++;
}
bool find(ll k)
{
    int p=abs(k)%mo;
    for(int i=h[p];~i;i=n1[i])
    {
        if(v[i]==k)return true;
    }
    return false;

}
void clearh()
{
    memset(h,-1,sizeof(h));
    ee=0;
}
bool check()
{
    clearh();
    ins(0);
    for(int i=1;i<=n;i++)
    {
        if(i%2==0)ins(sum[i]);
        if(find(sum[i]-k))return true;
    }
    clearh();
    //ou
    for(int i=1;i<=n;i++)
    {
        sum[i]=-sum[i];
        if(i%2==1)ins(sum[i]);
        if(find(sum[i]-k))return true;
    }
    return false;
}
int getint() {
    int ret=0;bool ok=0,neg=0;
    for(;;) {
        int c=getchar();
        if(c>=0&&c<=9)ret=(ret<<3)+ret+ret+c-0,ok=1;
        else if(ok)return neg?-ret:ret;
        else if(c==-)neg=1;
    }
}

int main()
{
    int T;
    T=getint();
    for(int cas=1;cas<=T;cas++)
    {
        n=getint();
        k=getint();
        for(int i=1;i<=n;i++)a[i]=getint();
        for(int i=1;i<=n;i++){
            if(i%2==1)sum[i]=sum[i-1]+a[i];
            else sum[i]=sum[i-1]-a[i];
        }
        printf("Case #%d: ",cas);
        if(check())puts("Yes.");
        else puts("No.");
    }
    return 0;
}

 

二次探测法:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define mo 1000007
#define inf 2147000000
int a[1000010];
ll sum[1000010];
int n,k;
ll h[mo];
void ins(ll k)
{
 //   return abs(k)%mo;
    ll p=abs(k),pp;
    for(int i=1;i<=n;i++)
    {
        pp=(p+i*i)%mo;
        if(h[pp]==inf){
            h[pp]=k;
            return;
        }
        pp=((p-i*i)%mo+mo)%mo;
        if(h[pp]==inf){
            h[pp]=k;
            return;
        }

    }
}
bool find(ll k)
{
    ll p=abs(k),pp;
    for(int i=1;i<=n;i++)
    {
        pp=(p+i*i)%mo;
        if(h[pp]==inf)return 0;
        if(h[pp]==k){
            return 1;
        }
        pp=((p-i*i)%mo+mo)%mo;
        if(h[pp]==inf)return 0;
        if(h[pp]==k){
            return 1;
        }

    }
    return 0;

}
void clearh()
{
    for(int i=0;i<mo;i++)h[i]=inf;
}
bool check()
{
    clearh();
    ins(0);
    //ji
    for(int i=1;i<=n;i++)
    {
        if(i%2==0)ins(sum[i]);
        if(find(sum[i]-k))return true;
    }
    clearh();
    //ou
    for(int i=1;i<=n;i++)
    {
        sum[i]=-sum[i];
        if(i%2==1)ins(sum[i]);
        if(find(sum[i]-k))return true;
    }
    return false;
}
int getint() {
    int ret=0;bool ok=0,neg=0;
    for(;;) {
        int c=getchar();
        if(c>=0&&c<=9)ret=(ret<<3)+ret+ret+c-0,ok=1;
        else if(ok)return neg?-ret:ret;
        else if(c==-)neg=1;
    }
}

int main()
{
    int T;
    T=getint();
    for(int cas=1;cas<=T;cas++)
    {
        n=getint();
        k=getint();
        for(int i=1;i<=n;i++)a[i]=getint();
        for(int i=1;i<=n;i++){
            if(i%2==1)sum[i]=sum[i-1]+a[i];
            else sum[i]=sum[i-1]-a[i];
        }
        printf("Case #%d: ",cas);
        if(check())puts("Yes.");
        else puts("No.");
    }
    return 0;
}

 

bc#32-2 Positive and Negative

标签:

原文地址:http://www.cnblogs.com/kylehz/p/4322644.html

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