博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【HASH】【UVA 10125】 Sumset
阅读量:5975 次
发布时间:2019-06-20

本文共 2679 字,大约阅读时间需要 8 分钟。

Description

  给定一个整数集合S,求一个最大的d,满足a+b+c=d,其中a,b,c,d∈S

Input

  多组数据,每组数据包括:

  • 第一行一个整数n,代表元素个数
  • 下面n行每行一个整数,代表集合元素

  输入结束的标志为n=0。

Output

  对于每组数据,输出:

  • 一行,如果有解,输出一个整数,代表最大的d;否则输出no solution

Sample Input

523571252166425610240

Sample Output

12no 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#include
#include
#include
#define rg register#define ci const intinline void qr(int &x) { char ch=getchar(),lst=NULL; while(ch>'9'||ch<'0') lst=ch,ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); if (lst=='-') x=-x;}char buf[20];inline void write(int x,const char aft,const bool pt) { if(x<0) {putchar('-');x=-x;} int top=0; do { buf[++top]=x%10+'0'; x/=10; } while(x); while(top) putchar(buf[top--]); if(pt) putchar(aft);}template
inline T mmax(const T &a,const T &b) {
if(a>b) return a;return b;}template
inline T mmin(const T &a,const T &b) { if(a
inline T mabs(const T &a) { if(a<0) return -a;return a;}template
inline void mswap(T &a,T &b) {T temp=a;a=b;b=temp;}const int maxn = 1010;const int maxt = 1000010;const int upceil = 19260817;struct HASH { int v,nxt,a,b;};HASH lst[maxt];int hd[upceil+1],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<<1)+(x>>1))&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=1;i<=n;++i) qr(MU[i]); std::sort(MU+1,MU+1+n); for(rg int i=1;i<=n;++i) for(rg int j=i+1;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=1;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=0;qr(n); }}void clear() { memset(hd,0,sizeof hd); memset(MU,0,sizeof MU); memset(lst,0,sizeof lst); cnt=0;}

Summary

考虑存储一个元素的多个信息且map复杂度超标的时候,不妨考虑HASH。

转载于:https://www.cnblogs.com/yifusuyi/p/9440390.html

你可能感兴趣的文章
Atom 编辑器系列视频课程
查看>>
[原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)
查看>>
mybatis update返回值的意义
查看>>
expdp 详解及实例
查看>>
通过IP判断登录地址
查看>>
深入浅出JavaScript (五) 详解Document.write()方法
查看>>
Beta冲刺——day6
查看>>
在一个程序中调用另一个程序并且传输数据到选择屏幕执行这个程序
查看>>
代码生成工具Database2Sharp中增加视图的代码生成以及主从表界面生成功能
查看>>
关于在VS2005中编写DLL遇到 C4251 警告的解决办法
查看>>
提高信息安全意识对网络勒索病毒说不
查看>>
我的友情链接
查看>>
IDE---Python IDE之Eric5在window下的安装
查看>>
Mybatis调用Oracle中的存储过程和function
查看>>
基本安装lnmp环境
查看>>
yum源资料汇总
查看>>
7、MTC与MTV,http请求介绍
查看>>
logstash消费阿里云kafka消息
查看>>
unix 环境高级编程
查看>>
MAXIMO 快速查找实现
查看>>