题意:问有没有数对(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 lll sum[N];
const unsigned long long SMod=;
struct hashmap{
struct Edge
{
long long num;
int next;
};
Edge edge[*N];
int countedge;
int head[SMod+]; void init()
{
memset(head,-,sizeof(head));
countedge=;
} 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!=-; ind=edge[ind].next)
{
if(edge[ind].num==num)break;
}
return ind;
}
}ST; int main()
{
int n,i,j,cs = ,t,x,K;
scanf("%d",&t);
while(t--)
{
ST.init();
scanf("%d%d",&n,&K);
sum[] = ;
for(i=;i<=n;i++) {
scanf("%d",&x);
if(i%) sum[i] = sum[i-] + x;
else sum[i] = sum[i-] - x;
}
ST.addedge(sum[n]);
int tag = ;
for(i=n-;i>=;i--) {
if(i% == && ST.Find(sum[i]+K) != -) { tag = ; break; }
if(i% && ST.Find(sum[i]-K) != -) { tag = ; break; }
ST.addedge(sum[i]);
}
printf("Case #%d: ",cs++);
if(tag) puts("Yes.");
else puts("No.");
}
return ;
}

枚举终点法

建立两个hashmap,一个记录sum[1],sum[3],...sum[2*cnt+1] (2*cnt+1<=n)即奇数位置是否出现过,另一个记录偶数位置的sum值是否出现过。

枚举终点y的话,起点可能是1~y的任何一个(这里下标从题目中的0~n-1转为了1~n),当起点x=1的时候,这时NP-SUM(x,y) = sum[y], 记为XX。以n=4为例。

那么起点为2的时候整个值就等于 -XX+a1, (-(a1-a2+a3-a4) +a1 = a2-a3+a4))

起点为3的时候整个值等于 XX-sum[2]      (a1-a2+a3-a4 - (a1-a2) = a3-a4 )

...以此类推,归为两类 :

1. XX-sum[0] , XX-sum[2] , ... XX-sum[偶数] 是否为K

2. -XX+sum[1], -XX+sum[3], ... -XX+sum[奇数] 是否为K

设他们为K,那么即判断 XX-K在偶数的hashmap中有没有出现, 判断XX+K在奇数的hashmap中有没有出现。

每次将sum[i]加入到对应的hashmap中。

顺序枚举。

代码:

#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=;
struct hashmap{
struct Edge
{
long long num;
int next;
};
Edge edge[*N];
int countedge;
int head[SMod+]; void init()
{
memset(head,-,sizeof(head));
countedge=;
} 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!=-; ind=edge[ind].next)
{
if(edge[ind].num==num)break;
}
return ind;
}
}mpe,mpo; int main()
{
int n,i,j,cs = ,t,x,K;
scanf("%d",&t);
for(cs=;cs<=t;cs++)
{
mpo.init();
mpe.init();
scanf("%d%d",&n,&K);
lll sum = ;
mpe.addedge();
int tag = ;
for(i=;i<=n;i++) {
scanf("%d",&x);
if(i&) sum += x;
else sum -= x;
if(i&) mpo.addedge(sum);
else mpe.addedge(sum);
if(mpe.Find(sum-K) != -) { tag = ; }
if(mpo.Find(sum+K) != -) { tag = ; }
}
printf("Case #%d: ",cs);
if(tag) puts("Yes.");
else puts("No.");
}
return ;
}

注意:

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

hashmap模板借鉴了love_dn的代码。

HDU 5183 Negative and Positive (NP) --Hashmap的更多相关文章

  1. hdu 5183 Negative and Positive (NP)

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5183 Negative and Positive (NP) Description When give ...

  2. HDU 5183 Negative and Positive (NP) (手写哈希)

    题目链接:HDU 5183 Problem Description When given an array \((a_0,a_1,a_2,⋯a_{n−1})\) and an integer \(K\ ...

  3. HDU 5183 Negative and Positive (NP) (hashmap+YY)

    学到了以邻接表方式建立的hashmap 题意:给你一串数a和一个数k,都有正有负,问知否能找到一对数(i,j)(i<=j)保证a [i] - a [i+1] + a [i+2] - a [i+3 ...

  4. HDU 5183 Negative and Positive (NP) 前缀和+哈希

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183 bc(中文):http://bestcoder.hdu.edu.cn/contests ...

  5. HDU 5183 Negative and Positive (NP) ——(后缀和+手写hash表)

    根据奇偶开两个hash表来记录后缀和.注意set会被卡,要手写hash表. 具体见代码: #include <stdio.h> #include <algorithm> #in ...

  6. hdu 5183 Negative and Positive (NP)(STL-集合【HASH】)

    题意: When given an array (a0,a1,a2,⋯an−1) and an integer K, you are expected to judge whether there i ...

  7. hdu 5183. Negative and Positive (哈希表)

    Negative and Positive (NP) Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  8. [HDOJ 5183] Negative and Positive (NP) 【Hash】

    题目链接:HDOJ - 5183 题目分析 分两种情况,奇数位正偶数位负或者相反. 从1到n枚举,在Hash表中查询 Sum[i] - k ,然后将 Sum[i] 加入 Hash 表中. BestCo ...

  9. hdu 5183(hash)

    传送门:Negative and Positive (NP) 题意:给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP− ...

随机推荐

  1. CSS基础之居中显示

    这些天忙完了一些项目后,终于有时间来总结一下了.自己就把做项目过程中的体会和理解到的一些东西和大家分享一下.有错请指正!! 在css中,元素居中显示,是基础也是一个小难点.我们经常不知为何总是不能把元 ...

  2. python读取文件的方法

    一. 通过readline 逐行读取: #--encoding:utf-8 with open("ha.conf","r",encoding='utf-8') ...

  3. oracle触发器详解

    触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 1.触发器类型 触发器在数据库里以独立的对象存储,它与存储过程和 ...

  4. for循环语句的笔试

    首先对for循环的初始条件进行调用打印A,之后判断语句输出B,第三个条件先不使用,直接进入循环内部 打印D,再到C:第二次判断i=1,A这个条件不使用了,进入B判定,再是D,C,最后进行判定输出B

  5. 【Nginx 大系】Nginx服务器面面观

    Nginx官方文档中文版 1. 先看看百度百科对Nginx 的解释: nginx_百度百科 2. 下面的博客就是讲 Nginx的安装方法和 具体的配置文件的使用介绍的很详细,可以仔细阅读下 [好]Ng ...

  6. jquery中 $(document).ready()和window.onload的区别

    1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行. $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕. 2.编写个数不同 ...

  7. Android 轻松实现仿淘宝地区选择

    介绍 最近用淘宝客户端的时候,编辑地址的时候有个地区选择的功能.看上面的效果觉得挺酷,滚动的时候,是最后一个从下面飞上来挨着前一个.就自己鼓捣一个出来玩玩. 说了效果可能不太直观,下面上两张图看看效果 ...

  8. databtables 设置(显示)行号

    var table = $('#priceStrategtyTable').DataTable({         "rowCallback": function( row, da ...

  9. Linux(RHEL6.0)下安装GCC

    查看系统版本 [root@CP-RHEL proc]# cat /etc/issue Red Hat Enterprise Linux Server release 6.0 (Santiago) Ke ...

  10. Spring 中classPath:用法

    参考文章地址: http://hi.baidu.com/huahua035/item/ac8a27a994b55bad29ce9d39 http://blog.csdn.net/lushuaiyin/ ...