【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+ ...
随机推荐
- 【Flutter】功能型组件之颜色和主题
前言 Color类中颜色以一个int值保存,显示器颜色是由红.绿.蓝三基色组成,每种颜色占8比特,存储结构如下: Bit(位) 颜色 0-7 蓝色 8-15 绿色 16-23 红色 24-31 Alp ...
- 【Spring】Spring中的Bean - 4、Bean的生命周期
Bean的生命周期 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 了解Spring中Bean的生命周期有何意义? 了解Sp ...
- vue路由切换和用location切换url的区别
最近的业务涉及到了axios的拦截器,要在request.js里面要根据状态码来跳转页面,这时候我就面对了几种跳转选择: 1.使用location.href='/url'来跳转,简单方便,但是刷新了页 ...
- me21n增强BADI:ME_PROCESS_PO_CUST之process_account
当实施ME_PROCESS_PO_CUST这个badi来增强ME21N的时候,用了到方法process_account,既对ME21N的行项目的科目分配做增强.主要用到如下类: IF_PURCHASE ...
- 阿里云VOD(一)
一.阿里云视频点播 1.功能介绍 视频点播(ApsaraVideo VoD,简称VoD)是集视频采集.编辑.上传.媒体资源管理.自动化转码处理(窄带高清TM).视频审核分析.分发加速于一体的一站式音视 ...
- kettle数据质量统计
1.利用Kettle的"分组","JavaScript代码","字段选择"组件,实现数据质量统计.2.熟练掌握"JavaScrip ...
- linux机器查看几个网卡以及型号
1.今天收到一台服务器,上去验收查看到机器有6个网卡,有点蒙,记录下查询网卡信息经过 2.一直不明白enp3s0f1这网口咋来的,去网上搜了下这个命名的基本是外插网卡板卡, 3.然后查看这个所有端口信 ...
- Serverless对研发效能的变革和创新 云托管和Serverless应用差异
https://mp.weixin.qq.com/s/J4RXtKanh3IMr4fY7t0nyQ Serverless对研发效能的变革和创新 杨皓然(不瞋) 阿里巴巴中间件 2020-10-23
- gin框架之路由前缀树初始化分析
https://mp.weixin.qq.com/s/lLgeKMzT4Q938Ij0r75t8Q
- LDAP学习
.top pre { display: block; background: rgba(68, 67, 65, 1); color: rgba(255, 255, 255, 1); margin: 1 ...