【HASH】【UVA 10125】 Sumset
Description
给定一个整数集合S,求一个最大的d,满足a+b+c=d,其中a,b,c,d∈S
Input
多组数据,每组数据包括:
- 第一行一个整数n,代表元素个数
- 下面n行每行一个整数,代表集合元素
输入结束的标志为n=0。
Output
对于每组数据,输出:
- 一行,如果有解,输出一个整数,代表最大的d;否则输出no solution
Sample Input
Sample Output
no solution
Hint
n≤1000,保证输入的集合元素互不相同。
集合中的元素∈[-536 870 912,536 870 911]。
Solution
考虑暴力做法:暴力枚举a,b,c,d,复杂度O(n4),无法承受。
考虑对于给定的d,和c,有唯一确定的a+b的值与之对应。所以我们考虑使用O(n2)的时间枚举可以产生的a+b的值并进行存储,然后枚举d和c,计算出d-c=a+b,判断是否可行。
如何存储a+b呢?普通数组显然开不下,考虑使用set或者map,我们发现在极端情况下,整个算法的复杂度为O(n2logn)。大概是108大小的运算量。考虑到多组数据,这个这个复杂度要GG。
考虑使用HASH,将a+b的值作为hash值,在信息中存储a+b的值,a的下标和b的下标,将hash值相同的按照链式前向星的形式挂成链。期望意义下的复杂度为O(n2),可以通过本题。
另外,如果担心取模变慢,在代码中我采取了&19260817的方式代替取模,但是在链的长度上,应该不如膜大质数的方式。科学性有待考证
Code
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register
#define ci const int inline void qr(int &x) {
char ch=getchar(),lst=NULL;
while(ch>''||ch<'') lst=ch,ch=getchar();
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
if (lst=='-') x=-x;
} char buf[];
inline void write(int x,const char aft,const bool pt) {
if(x<) {putchar('-');x=-x;}
int top=;
do {
buf[++top]=x%+'';
x/=;
} while(x);
while(top) putchar(buf[top--]);
if(pt) putchar(aft);
} template <typename T>
inline T mmax(const T &a,const T &b) {if(a>b) return a;return b;}
template <typename T>
inline T mmin(const T &a,const T &b) {if(a<b) return a;return b;}
template <typename T>
inline T mabs(const T &a) {if(a<) return -a;return a;} template <typename T>
inline void mswap(T &a,T &b) {T temp=a;a=b;b=temp;} const int maxn = ;
const int maxt = ;
const int upceil = ; struct HASH {
int v,nxt,a,b;
};
HASH lst[maxt];int hd[upceil+],cnt;
inline void ist(ci v,ci key,ci a,ci b) {
HASH &now=lst[++cnt];
now.v=v;now.nxt=hd[key];now.a=a;now.b=b;hd[key]=cnt;
} inline int get_HASH(ci x) {
return ((x<<)+(x>>))&upceil;
} inline bool judge(ci a,ci b,ci c,ci d) {
if(a==c||a==d||b==c||b==d) return false;
return true;
} int n,MU[maxn]; void clear() ; int main() {
qr(n);
while(n) {
clear();
for(rg int i=;i<=n;++i) qr(MU[i]);
std::sort(MU+,MU++n);
for(rg int i=;i<=n;++i)
for(rg int j=i+;j<=n;++j) {
ist(MU[i]+MU[j],get_HASH(MU[i]+MU[j]),i,j);
}
for(rg int i=n;i;--i) {
for(rg int j=;j<=n;++j) if(i!=j) {
int delta=MU[i]-MU[j];
int k=get_HASH(delta);
if(!hd[k]) continue;
for(int h=hd[k];h;h=lst[h].nxt) if(lst[h].v==delta) {
if(judge(lst[h].a,lst[h].b,i,j)) {write(MU[i],'\n',true);goto loop;}
}
}
}
puts("no solution");
loop:
n=;qr(n);
}
} void clear() {
memset(hd,,sizeof hd);
memset(MU,,sizeof MU);
memset(lst,,sizeof lst);
cnt=;
}
Summary
考虑存储一个元素的多个信息且map复杂度超标的时候,不妨考虑HASH。
【HASH】【UVA 10125】 Sumset的更多相关文章
- 51nod 1095 Anigram单词【hash/map/排序/字典树】
1095 Anigram单词 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 一个单词a如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b ...
- [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...
- 【HDOJ3567】【预处理bfs+映射+康拓展开hash】
http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others) Me ...
- POJ 1200 Crazy Search【Hash入门】
RK法:https://www.cnblogs.com/16crow/p/6879988.html #include<cstdio> #include<string> #inc ...
- 【UVa 10881】Piotr's Ants
Piotr's Ants Porsition:Uva 10881 白书P9 中文改编题:[T^T][FJUT]第二届新生赛真S题地震了 "One thing is for certain: ...
- 【UVa 116】Unidirectional TSP
[Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- 【UVa 1347】Tour
[Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- 【UVA 437】The Tower of Babylon(记忆化搜索写法)
[题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- 【uva 1025】A Spy in the Metro
[题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
随机推荐
- TW实习日记:第20-21天
为什么上周五没写呢,因为上周五一直在熟悉业务流程...根本不会写一些复杂的业务代码,因为没有业务流程图!!!在学校的上需求分析和UML建模课的时候,还有软件工程课的时候,想着这都什么鬼啊,听来干嘛,写 ...
- leetcode个人题解——#20 Valid Parentheses
class Solution { public: bool isValid(string s) { stack<char> brackts; ; i < s.size(); i++) ...
- 6.hdfs的存储过程
1.hdfs 怎么存储 切割存储 2. 为何每块是128m 与io读写速度有关,一般人的接受速度1s中,而磁盘的读写速度为100m/s,在读取文件时候需要硬盘寻找地址,一般读懂速度和寻找之间的比例是1 ...
- HDU 1569 方格取数(2)(最大流最小割の最大权独立集)
Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. ...
- 软工Hello World!团队第二周博客汇总
2017.10.20-2017.10.26 Scrum会议: 第一天:http://www.cnblogs.com/liusx0303/p/7704482.html 第二天:http://www.cn ...
- android仿美团客户端购买框悬浮特效
实现步骤如下: 1,新建一个项目,新建一个MyScrollView继承自ScrollView public class MyScrollView extends ScrollView { ...
- aria2 on ubuntu
http://www.5yun.org/9102.html http://jpollo.logdown.com/posts/160847-aria2c-and-yaaw aria2c --enable ...
- String 和 CharSequence 关系与区别
String 继承于CharSequence,也就是说String也是CharSequence类型. CharSequence是一个接口,它只包括length(), charAt(int index) ...
- spring框架(1)— 依赖注入
依赖注入 spring核心容器就是一个超级大工厂,所以的对象(数据源.hibernate SessionFactory等基础性资源)都会被当做spring核心容器的管理对象——spring把容器中的一 ...
- TCP系列16—重传—6、基础快速重传(Fast Retransmit)
一.快速重传介绍 按照TCP协议,RTO超时重传是一个非常重要的事件,当RTO超时的时候,TCP会同时通过两种方式非常谨慎的降低发送数据包的速率,一种是基于拥塞控制削减发送窗口的大小,另外一个是通过指 ...