【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)
题意:给定4个N元素几个A,B,C,D,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0。问有多少种选法。(N≤4000,D≤2^28)
解法:首先我们从最直接最暴力的方法开始思考:四重循环O(n^4)枚举;三重循环枚举,把剩下的一个集合排序后二分查找,O(n^3 log n)。在进一步想,运用“中途相遇法”:从两个不同的方向来解决问题,最后“汇集”到一起的方法。(有类似于“双向广度优先搜索”的思想)通过两重循环枚举出A,B两个集合中的元素可组成的和,一般想到开个以和为值的数组记录个数。但是由于D值有2^28这么大,所以不行。于是——解决技巧很厉害!(。ì _ í 。)
实现1:既然不能将相同的数一个个竖向累积在一个数组位,那就可以把这些相同的数横向拉伸,排成一排。使用STL库头文件algorithm里的upper_bound和lower_bound函数直接查找到>d和>=d的数的位置,相减就是d值的数的个数。这样的时间复杂度是O(n^2 log n)。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5 #include<iostream>
6 using namespace std;
7
8 const int N=4010;
9 int a[N],b[N],c[N],d[N],sum[N*N];
10
11 int main()
12 {
13 int T;
14 scanf("%d",&T);
15 while (T--)
16 {
17 int n;
18 scanf("%d",&n);
19 for (int i=1;i<=n;i++)
20 scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
21 int m=0;
22 for (int i=1;i<=n;i++)
23 for (int j=1;j<=n;j++)
24 sum[++m]=a[i]+b[j];
25 sort(sum+1,sum+1+m);
26 long long cnt=0;//long long
27 for (int i=1;i<=n;i++)
28 for (int j=1;j<=n;j++)
29 cnt+=upper_bound(sum+1,sum+1+m,-c[i]-d[j])-lower_bound(sum+1,sum+1+m,-c[i]-d[j]);
30 printf("%lld\n",cnt);
31 if (T) printf("\n");
32 }
33 return 0;
34 }
STL库实现
实现2:当然检索的高效算法 Hash也是可以的。我这里用的是闭散列表储存,即%一个大整数(一般是质数)之后放在相应的位置。若该位置已存储了其他数,则将这个数一直往后推直到一个空的位置。由于和的个数最多为n^2,小于列表的长度足够存储,那么就算和的值很大也不影响了。
关于具体代码我再解释一些:1.常量的0x7fffff表示16进制的7fffff,f是15,即2^23;2.结构体哈希表重载了运算符[],这样就可以直接得到每个数的个数了;3.用&运算而不是%,可能是因为运算速度或存储空间,改成%就RE,但其实它们的意思是一样的,目的都是使数较集中的放在一起。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 const int N=4010;
8 int a[N],b[N],c[N],d[N];
9
10 struct ha_map
11 {
12 static const int mod=0x7fffff;
13 int s[mod+1],d[mod+1];
14 void clear() {memset(s,0,sizeof(s));}
15 int& operator [] (int x)
16 {
17 int i;
18 for (i=x&mod;s[i]&&d[i]!=x;i=(i+1)&mod);
19 d[i]=x;
20 return s[i];
21 }
22 }ha;
23
24 int main()
25 {
26 int T;
27 scanf("%d",&T);
28 while (T--)
29 {
30 int n;
31 scanf("%d",&n);
32 for (int i=1;i<=n;i++)
33 scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
34 ha.clear();
35 for (int i=1;i<=n;i++)
36 for (int j=1;j<=n;j++)
37 ha[a[i]+b[j]]++;
38 long long cnt=0;//long long
39 for (int i=1;i<=n;i++)
40 for (int j=1;j<=n;j++)
41 cnt+=ha[-c[i]-d[j]];
42 printf("%lld\n",cnt);
43 if (T) printf("\n");
44 }
45 return 0;
46 }
Hash实现
Hash的速度是STL库的4倍多~~ (-ω-*)
【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)的更多相关文章
- UVA 1152 4 Values whose Sum is 0 (枚举+中途相遇法)(+Java版)(Java手撕快排+二分)
4 Values whose Sum is 0 题目链接:https://cn.vjudge.net/problem/UVA-1152 ——每天在线,欢迎留言谈论. 题目大意: 给定4个n(1< ...
- uva 1152 4 values whose sum is zero ——yhx
The SUM problem can be formulated as follows: given four lists A;B;C;D of integer values, computehow ...
- UVa 1152 -4 Values whose Sum is 0—[哈希表实现]
The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute ...
- UVA - 1152 4 Values whose Sum is 0(中途相遇法)
题意:从四个集合各选一个数,使和等于0,问有多少种选法. 分析:求出来所有ai + bi,在里面找所有等于ci + di的个数. #pragma comment(linker, "/STAC ...
- UVa 1152 4 Values whose Sum is 0
题意:给出n,四个集合a,b,c,d每个集合分别有n个数,分别从a,b,c,d中选取一个数相加,问使得a+b+c+d=0的选法有多少种 看的紫书,先试着用hash写了一下, 是用hash[]记录下来a ...
- UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
摘要:中途相遇.对比map,快排+二分查找,Hash效率. n是4000的级别,直接O(n^4)肯定超,所以中途相遇法,O(n^2)的时间枚举其中两个的和,O(n^2)的时间枚举其他两个的和的相反数, ...
- UVA - 1152 4 Values whose Sum is 0问题分解,二分查找
题目:点击打开题目链接 思路:暴力循环显然会超时,根据紫书提示,采取问题分解的方法,分成A+B与C+D,然后采取二分查找,复杂度降为O(n2logn) AC代码: #include <bits/ ...
- UVA - 1152 --- 4 Values whose Sum is 0(二分)
问题分析 首先枚举a和b, 把所有a+b记录下来放在一个有序数组,然后枚举c和d, 在有序数组中查一查-c-d共有多少个.注意这里不可以直接用二分算法的那个模板,因为那个模板只能查找是否有某个数,一旦 ...
- uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)
用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度. 这里用到一个很实用的技巧: 求长度为n的有序数组a中的数k的个数num? num=upper_bound(a,a+ ...
随机推荐
- ClickHouse安装使用(单机、集群、高可用)
Clickhouse版本:20.3.6.40-2 安装包地址:https://repo.yandex.ru/clickhouse/rpm/stable/x86_64/ 一.单机版 1.安装依赖 yum ...
- 给mysql选择调度策略
在gun/linux上,队列调度决定了到块设备的请求实际上发送到底层设置的顺序.默认情况下是cfg(完全公平排队)策略,随意使用的笔记本和台式机使用中个调度策略没有问题,并且有助于防止io饥饿,但是用 ...
- ASP.NET Core错误处理中间件[2]: 开发者异常页面
<呈现错误信息>通过几个简单的实例演示了如何呈现一个错误页面,该过程由3个对应的中间件来完成.下面先介绍用来呈现开发者异常页面的DeveloperExceptionPageMiddlewa ...
- rac双节点+物理DG
注:以下文章均是看了黄伟老师的视频,记录为博客供以后使用. 双节点RAC搭建: http://blog.csdn.net/imliuqun123/article/details/76171289 RA ...
- WeihanLi.Npoi 1.14.0 Release Notes
WeihanLi.Npoi 1.14.0 Release Notes Intro 周末更新了一下项目,开始使用可空引用类型,并且移除了 net45 的支持,仅支持 netstandard2.0 Cha ...
- three.js cannon.js物理引擎地形生成器和使用指针锁定控件
今天郭先生说一说使用cannon.js物理引擎绘制地形和使用指针锁定控件.效果如下图.线案例请点击博客原文. 这里面的生成地形的插件和指针锁定控件也是cannon.js的作者schteppe封装的,当 ...
- uni-app开发经验分享四: 实现文字复制到选择器中
这里分享一个我经常用到的一个方法,主要是用来复制文字内容,具体代码如下: var that=this; if(!document){ uni.setClipboardData({ data:复制的值, ...
- 一个简单的IM聊天程序Pie IM(以后会更新)
这个程序用多线程,实现设备之间的聊天,支持win10通知,欢迎下载 依赖的第三方库 win10toast 代码 将以下代码写入任意.py文件 1 print('Welcome to use Pie I ...
- ctfshow_djb杯
桐桑又开始摸鱼了 ctfshow的比赛整的一手好活.djb杯. web1_veryphp 打开就是源码: 1 <?php 2 error_reporting(0); 3 highlight_fi ...
- 数字化转型中企业真正困惑-传统IT架构如何改造和全面上云
对数字化转型,整体来看大部分人相对关心问题主要还是集中在以下两个方面. 企业传统的IT架构如何如何微服务改造,演进发展 企业传统IT如何全面上云和实施云原生 以上两点实际都包括一个关键点,即企业当前内 ...