您的位置:首页 > 其它

HDU 5183 Negative and Positive (NP) --Hashmap

2015-03-08 15:28 411 查看
题意:问有没有数对(i,j)(0<=i<=j<n),使得a[i]-a[i+1]+...+(-1)^(j-i)a[j]为K.

解法:两种方法,枚举起点或者枚举终点。

先保存前缀和:a1-a2+a3....+/- an

枚举起点法: 设起点为x,实际是枚举x-1,分两种情况:

1.起点x为奇,那么就看有没有a[j]-a[x-1] = K的,即a[j] = a[x-1]+K。因为奇数位置的ai数符为正。

2.起点x为偶,那么就看有没有a[j]-(-K) = a[x-1],即a[j] = a[x-1]-K。因为偶数位置ai数符为负,即x到j这一段的数是负的 选x为起点的x到j的这一段和,所以中间实际上是-K。

每次将sum[i]标记为出现过。

只需要一个hashmap即可。

由于枚举到一个起点x,需要判断a[j](j>x)是否出现,所以要逆序枚举。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
#define lll __int64
#define ll long long
using namespace std;
#define N 1000007

const unsigned long long SMod=1000007;
struct hashmap{
struct Edge
{
long long num;
int next;
};
Edge edge[2*N];
int countedge;
int head[SMod+100];

void init()
{
memset(head,-1,sizeof(head));
countedge=0;
}

void addedge(long long num)
{
int start=num%SMod;
edge[countedge].next=head[start];
edge[countedge].num=num;
head[start]=countedge;
countedge++;
}

int Find(long long num)
{
int start=num%SMod;
int ind;
for(ind=head[start]; ind!=-1; ind=edge[ind].next)
{
if(edge[ind].num==num)break;
}
return ind;
}
}mpe,mpo;

int main()
{
int n,i,j,cs = 1,t,x,K;
scanf("%d",&t);
for(cs=1;cs<=t;cs++)
{
mpo.init();
mpe.init();
scanf("%d%d",&n,&K);
lll sum = 0;
mpe.addedge(0);
int tag = 0;
for(i=1;i<=n;i++) {
scanf("%d",&x);
if(i&1) sum += x;
else    sum -= x;
if(i&1) mpo.addedge(sum);
else    mpe.addedge(sum);
if(mpe.Find(sum-K) != -1) { tag = 1; }
if(mpo.Find(sum+K) != -1) { tag = 1; }
}
printf("Case #%d: ",cs);
if(tag) puts("Yes.");
else    puts("No.");
}
return 0;
}


View Code

注意:

如果hashmap中的SMod 用宏定义的方式就会T, 用const unsigned long long 就不会。不知道为什么。

hashmap模板借鉴了love_dn的代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: