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− ...
随机推荐
- 获取linux服务器基本信息脚本
为了方便日常运维写的一段简单脚本,用于集中获取服务器操作系统.CPU.内存使用.负载.硬盘使用.网络信息. 脚本比较简单,就不解释了,有兴趣的朋友请自行查看. #!/bin/bash##Name:sy ...
- ubuntu入门
Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音.了解发音是有意义的,您不是第一个为此困惑的人,当然,也不会是最后一个:) 大多数的美国人读 ubun ...
- swoole_redis 记一次看文档不仔细做警醒
测试代码 $redisClass = new Redis(); $redisClass->connect('127.0.0.1', 6379, 1); $result = $redisClass ...
- 【新技术】Docker 学习笔记
原文地址 一.Docker 简介 Docker 两个主要部件: Docker: 开源的容器虚拟化平台 Docker Hub: 用于分享.管理 Docker 容器的 Docker SaaS 平台 -- ...
- PowerDesigner15在win7-64位系统下对MySQL 进行反向工程以及建立物理模型产生SQL语句步骤图文傻瓜式详解
1.安装PowerDesigner15.MySQL5.不详细讲解了.网上一大把.请各位亲参考去. 2.安MyODBC-standard-3.51.0.7-win.msi.mysql-connector ...
- Lind.DDD.Events事件总线~自动化注册
回到目录 让大叔兴奋的自动化注册 对于领域事件之前说过,在程序启动时订阅(注册)一些事件处理程序,然后在程序的具体位置去发布(触发)它,这是传统的pub/sub模式的体现,当然也没有什么问题,为了让它 ...
- ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- springmvc整合mybatis框架源码 bootstrap
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单 下载地址 ; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类 ...
- jquery在线五子棋
在线五子棋试玩地址:http://keleyi.com/game/12/ 以下是完整代码,保存到html文件打开也可以玩: <!DOCTYPE html> <html> < ...
- AMD and CMD are dead之KMD.js版本0.0.2发布
更新 正式从UglifyJS切换至UglifyJS2 增加依赖可视化功能 压缩代码更加方便 统一风格:如main的class名也不能省略 优化了kmdjs管道 修复了无数bug 通过src开启debu ...