HDU 5183 Negative and Positive (NP) --Hashmap
题意:问有没有数对(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的更多相关文章
- hdu 5183 Negative and Positive (NP)
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5183 Negative and Positive (NP) Description When give ...
- 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\ ...
- 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 ...
- HDU 5183 Negative and Positive (NP) 前缀和+哈希
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183 bc(中文):http://bestcoder.hdu.edu.cn/contests ...
- HDU 5183 Negative and Positive (NP) ——(后缀和+手写hash表)
根据奇偶开两个hash表来记录后缀和.注意set会被卡,要手写hash表. 具体见代码: #include <stdio.h> #include <algorithm> #in ...
- 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 ...
- hdu 5183. Negative and Positive (哈希表)
Negative and Positive (NP) Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- [HDOJ 5183] Negative and Positive (NP) 【Hash】
题目链接:HDOJ - 5183 题目分析 分两种情况,奇数位正偶数位负或者相反. 从1到n枚举,在Hash表中查询 Sum[i] - k ,然后将 Sum[i] 加入 Hash 表中. BestCo ...
- hdu 5183(hash)
传送门:Negative and Positive (NP) 题意:给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP− ...
随机推荐
- iOS阶段学习第35天笔记(Touch手势介绍)
一.Touch手势 1.利用手势实现UIButton移动效果 实例代码 1) 创建一个继承自UIButton的类 MyButton.h 代码实现 #import <UIKit/UIKit.h ...
- cors解决webapi post时报错405 method not allowed
nuget控制台敲入以下命令:Install-Package Microsoft.AspNet.WebApi.Cors –IncludePrerelease 打开WebApiConfig.cs添加如下 ...
- Overload 和Override 的区别
Overload 是重载的意思,Override 是覆盖的意思,也就是重写.重载 Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同).重写 ...
- SpringMVC的注解开发入门
1.Spring MVC框架简介 支持REST风格的URL 添加更多注解,可完全注解驱动 引入HTTP输入输出转换器(HttpMessageConverter) 和数据转换.格式化.验证框架无缝集成 ...
- Java编程里类的继承
今天,我们将要讨论的内容是Java里面类的继承的相关概念. 说到继承,我相信大家都不陌生.生活中,子承父业,子女继承父母的财产,这就是继承.实际上,Java里的继承也是如此.对于一个类来说,它的数据成 ...
- java多线程-线程池
线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用.因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等. 我们可以把并发执行的任务传递给一个线程池, ...
- javascript中DOM部分基础知识总结
1.DOM介绍 1.1 DOM概念 文档对象模型(Document Object Model),它定义了访问和处理HTML文档的标准方法.现在我们主要接触到的是HTML DOM. ...
- [deviceone开发]-多种样式下拉菜单demo
一.简介 该demo主要展示了3种下拉菜单. 一.仿QQ弹出菜单 主要实现原理是通过add一个ui,然后通过点击事件控制其visible属性来显示或者隐藏. 二.组合下拉菜单 主要用到的控件是do_A ...
- [deviceone开发]-do_SegmentView和do_SlideView联动的示例
一.简介 示例展示do_SegmentView和do_SlideView联动的使用,这二个组件很常用,而且这个组合也非常常用,类似网易新闻的效果,上面滑动带动下面的slideview滑动,反过来也是. ...
- PowerDesigner 逆向工程 Mariadb 失败
作者环境是win8.1 64位置 PowerDesigner 15, Mariadb 10+,在逆向的过程中发生错误,导致只能逆向出表对象,但是表对象中的字段信息确实没有的. 错误信息中的一部分是: ...