题目传送门

题意:5个集合,每个集合最多200个数字,问是否每个集合挑一个数加起来和为0。

分析:显然n^5的程序果断超时,甚至n^3logn的二分也过不了。想n^3的方法,既然判断有没有,那么可以将两个两个的集合合并成两个大集合,再枚举最后一个集合,两个大集合排完序之后一个指针从开头最小开始,另一个从最大的开始,>0,大指针往左移,<0,小指针往右移,那么可以在线性时间求解,这贪心方法很巧妙!

另一种做法算是暴力+优化了,哈希表储存一个两个集合合并后大集合的数字,n^3暴力询问是否哈希表内存在它的相反数,哈希表用到链式前向星,总算有点理解了,贴张图:

收获:1. ”微调“贪心方法 2. 哈希表 + 链式前向星

代码1(贪心):

/************************************************
* Author :Running_Time
* Created Time :2015-8-26 9:07:01
* File Name :HDOJ_4334.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 2e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
ll a[5][N];
ll sum[2][N*N]; int main(void) {
int T; scanf ("%d", &T);
while (T--) {
int n; scanf ("%d", &n);
for (int i=0; i<5; ++i) {
for (int j=0; j<n; ++j) {
scanf ("%I64d", &a[i][j]);
}
}
int tot = 0;
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
sum[0][tot] = a[0][i] + a[1][j];
sum[1][tot++] = a[2][i] + a[3][j];
}
}
sort (sum[0], sum[0]+tot);
sort (sum[1], sum[1]+tot);
int cnt1 = 1, cnt2 = 1;
for (int i=1; i<tot; ++i) { //其实离散化没什么优化
if (sum[0][i] != sum[0][i-1]) sum[0][cnt1++] = sum[0][i];
if (sum[1][i] != sum[1][i-1]) sum[1][cnt2++] = sum[1][i];
} bool flag = false;
for (int i=0; i<n && !flag; ++i) {
for (int j=0,k=cnt2-1; j<cnt1 && k>=0; ) {
ll tmp = a[4][i] + sum[0][j] + sum[1][k];
if (tmp == 0) {
flag = true; break;
}
else if (tmp < 0) j++;
else k--;
}
} printf ("%s\n", flag ? "Yes" : "No");
} return 0;
}

代码2(哈希表):

/************************************************
* Author :Running_Time
* Created Time :2015-8-26 18:21:55
* File Name :D_2.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 2e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e6 + 7;
struct Hash_Table {
struct Edge {
ll x;
int nex;
}edge[MOD];
int head[MOD], E;
void init(void) {
memset (head, -1, sizeof (head));
E = 0;
}
void insert(ll x) {
int u = (x % MOD + MOD) % MOD;
for (int i=head[u]; ~i; i=edge[i].nex) {
if (edge[i].x == x) return ;
}
edge[E].x = x; edge[E].nex = head[u];
head[u] = E++;
}
bool find(ll x) {
int u = (x % MOD + MOD) % MOD;
for (int i=head[u]; ~i; i=edge[i].nex) {
if (edge[i].x == x) return true;
}
return false;
}
}ha;
ll a[5][N]; int main(void) {
int T; scanf ("%d", &T);
while (T--) {
int n; scanf ("%d", &n);
for (int i=0; i<5; ++i) {
for (int j=0; j<n; ++j) scanf ("%I64d", &a[i][j]);
}
ha.init ();
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
ha.insert (a[0][i] + a[1][j]);
}
}
bool flag = false;
for (int i=0; i<n && !flag; ++i) {
for (int j=0; j<n && !flag; ++j) {
for (int k=0; k<n; ++k) {
if (ha.find (-(a[2][i] + a[3][j] + a[4][k]))) {
flag = true; break;
}
}
}
}
puts (flag ? "Yes" : "No");
} return 0;
}

  

贪心+枚举/哈希表 HDOJ Trouble的更多相关文章

  1. 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem——哈希表&&二进制枚举

    题意 有长度为 $n$($1\leq n\leq 36$)的数列,给出 $s$,求和为 $s$ 的子集,保证子集存在且唯一. 分析 答案肯定是来自左右半边两部分组成的. 如果我们用哈希表存一半,计算另 ...

  2. 深入理解PHP内核(六)哈希表以及PHP的哈希表实现

    原文链接:http://www.orlion.ga/241/ 一.哈希表(HashTable) 大部分动态语言的实现中都使用了哈希表,哈希表是一种通过哈希函数,将特定的键映射到特定值得一种数据 结构, ...

  3. noip模拟赛 好元素 哈希表的第一题

    这是一道关于 题2好元素 2s [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i < ...

  4. c# 哈希表跟函数

    一.哈希表集合 先进后出,一个一个赋值,但只能一起取值. 1.哈希表的建立.赋值以及读取. 2.利用枚举类型打印出集合中的Key值和Value值. 二.函数 函数:能够独立完成某项功能的模块. 函数四 ...

  5. C#部分---特殊集合:stack栈集合、queue队列集合、哈希表集合。

    1.stack栈集合:又名 干草堆集合 栈集合 特点:(1)一个一个赋值 一个一个取值(2)先进后出实例化 初始化 Stack st = new Stack(); //添加元素用push st.Pus ...

  6. 哈希表(hashtable)的javascript简单实现

    javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...

  7. c# 哈希表集合;函数

    * 哈希表集合 1.先进去的后出来,最后进去的先出来 2.利用枚举类型打印出集合中的Key值和Value值 ** 函数 1.函数:能够独立完成某项功能的模块. 函数四要素:输入.输出.函数体.函数名 ...

  8. Gold Balanced Lineup(哈希表)

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10711   Accepted: 3182 Description Farm ...

  9. Stack集合 Queue队列集合 Hashtable哈希表

    Stack集合 干草堆集合 栈集合 栈;stack,先进后出,一个一个赋值,一个一个取值,安装顺序来. 属性和方法 实例化 初始化 Stack st = new Stack(); 添加元素 个数 Co ...

随机推荐

  1. DataGridView依据下拉列表显示数据

    我们都知道,DataGridView能够直接绑定数据源.显示数据库中的数据.可是我想做的是能够对他进行条件查询,依据用户级别选择不同级别的记录. 以上这个控件就是DataGridView控件,能够用它 ...

  2. Office EXCEL 如何保留一位小数,并且单击这个单元格的时候没有一大串小数

    左侧有一列数据,即便我设置单元格格式,把小数位数设为1,看上去的确四舍五入,保留一位小数了,但是实际上我鼠标双击任意单元格,还是原来的数值,这样的数据如果是要发给别人的,肯定不好   如果进行选择性粘 ...

  3. Swift String 一些经常用法

    直接上代码 //字符串 //1 推断字符串是否为空 var test1Str="" var test1Str2:String = String(); println("t ...

  4. 【HRS项目】Axure兴许问题解决---与SVN结合

    上一篇博客介绍了Axure的团队开发用法,http://blog.csdn.net/u013036274/article/details/50999139,可是再用的时候发现会出现这种问题,例如以下图 ...

  5. Visual Studio 2012 Fakes框架测试驱动开发TDD教程

    一.前言 最近团队要尝试TDD(测试驱动开发)的实践,很多人习惯了先代码后测试的流程,对于TDD总心存恐惧,认为没有代码的情况下写测试代码时被架空了,没法写下来,其实,根据个人实践经验,TDD并不可怕 ...

  6. Linux下用Xdebug调试php

    Linux下用Xdebug调试php 博客分类: php PHPLinuxZendEclipseC# 为了调试PHP程序,安装一下xdebug. 官方网址: http://www.xdebug.org ...

  7. 关于OutOfMemoryError的处理

    转自:http://www.blogjava.net/rosen/archive/2010/05/21/321575.html http://www.blogjava.net/rosen/archiv ...

  8. web 开发之js---页面缓存, jsp 缓存, html 缓存, ajax缓存,解决方法

    有关页面缓存问题.这个问题上网找了好多.但发觉各种解决方法,都彼此分离,没有一篇统一的解决方法,本人近日,也遇到了页面缓存的问题,根据网上各页面缓存的解答,做了一个总结. 1.服务器端缓存的问题, 防 ...

  9. bzoj3109【CQOI2013】新数独

    3109: [cqoi2013]新数独 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 365  Solved: 229 [Submit][Statu ...

  10. sql里的in对应linq的写法 及 IQueryable转化为Dictionary

    string[] arID = { "0001", "0002" }; var dict = this.service.GetMyList(m => ar ...