【高效算法设计-中途相遇法】4 Values whose Sum is 0 哈希表
来源:互联网 发布:.net java 区别 编辑:程序博客网 时间:2024/05/06 01:49
4 Values whose Sum is 0
Time Limit: 15000MS Memory Limit: 228000KTotal Submissions: 16375 Accepted: 4748Case Time Limit: 5000MS
Description
The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .
Input
The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .
Output
For each input file, your program has to write the number quadruplets whose sum is zero.
Sample Input
6-45 22 42 -16-41 -27 56 30-36 53 -37 77-36 30 -75 -4626 -38 -10 62-32 -54 -6 45
Sample Output
5
Hint
Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).
Source
Southwestern Europe 2005
题意:本题题意很简单,给定4组数,每组有n个数,从每组数中各取一个数,问有多少种取法使得取出的四个数之和为0
思路:很容易想到用暴力枚举的方法,时间复杂度为O(n^4),必然超时,而对于这种从集合中选组合类的问题,我们通常采用一种方法,即中途相遇法
中途相遇法:就是从两个方向向中间靠拢的一种做法,如双向BFS,对于此题,我们可以把前两组的组合和后两组的组合分开计算,然后再看是否之和为0,即我们先计算前两组数的和,利用数据结构存储起来,再计算后两组数的和,进行查询,这样时间复杂度就降低到O(n^2*查询的时间复杂度),由于本题数据范围较大,无法使用vis数组进行O(1)的查询,因此只能考虑使用map或者hash表
由于map的代码复杂度较低,时间复杂度为O(n^2*logn),我们可以先尝试用map写一个demo程序
使用map的代码如下
#include<cstdio>#include<cstring>#include<map>using namespace std;map<int,int>MAP;int a[5][5000];int main(){ int n,i,j,tt,ans; while(~scanf("%d",&n)) { ans=0; MAP.clear(); for(j=1;j<=n;j++) for(i=1;i<=4;i++) scanf("%d",&a[i][j]); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { tt=a[1][i]+a[2][j]; MAP[tt]++; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) { tt=a[3][i]+a[4][j]; ans+=MAP[-tt]; } printf("%d\n",ans); } return 0;}
很遗憾,使用map会超时,于是我们考虑使用hash,实现hash的方法主要使用开放寻址法或者哈希邻接表
利用head[]数组和next[]数组可以轻松完成哈希邻接表,我们使用除法取余作为哈希函数,head数组的大小为素数mod的大小,这里素数取得越大,发生碰撞的可能性就越小,next[]的大小为哈希表中一共需要存入数据个数的大小,即前两组数的组合个数,n^2
哈希AC代码如下:
#include<cstdio>#include<cstring>#include<cmath>using namespace std;//const int mod=3999971;const int mod=10000007;int head[mod+50];int next[16000000+50];int a[5][5000];int res[16000000+50];void insert_hash(int x){ int v=abs(res[x]%mod); next[x]=head[v]; head[v]=x;}int find_hash(int x){ int cnt=0; int t=abs(x); int u=head[t%mod]; while(u!=-1) { if(res[u]==x) cnt++; u=next[u]; } return cnt;}int main(){ int n,i,j,tt,ans,k; while(~scanf("%d",&n)) { ans=0; memset(head,-1,sizeof head); for(j=1;j<=n;j++) for(i=1;i<=4;i++) scanf("%d",&a[i][j]); k=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { tt=a[1][i]+a[2][j]; res[++k]=tt; insert_hash(k); } for(i=1;i<=n;i++) for(j=1;j<=n;j++) { tt=a[3][i]+a[4][j]; ans+=find_hash(-tt); } printf("%d\n",ans); } return 0;}
0 0
- 【高效算法设计-中途相遇法】4 Values whose Sum is 0 哈希表
- UVA 1152 4 Values whose Sum is 0 中途相遇法 二分查找
- uva1152 4 Values whose Sum is 0(中途相遇法)
- UVA 1152 --4 Values whose Sum is 0(枚举--中途相遇法)
- UVa1152 4 Values whose Sum is 0 (中途相遇法+二分)
- UVa 1152 - 4 Values whose Sum is 0(中途相遇)
- uva 1152 4 Values whose Sum is 0(二分_中途相遇|| hash)
- Uva1152 4 Values whose Sum is 0 【中途相遇+二分】【例题8-3】
- (白书训练计划)UVa 1152 4 Values whose Sum is 0(中途相遇法。。)
- 4 Values whose Sum is 0 (P2785)
- 4 Values whose Sum is 0
- 4 Values whose Sum is 0
- 2785 4 Values whose Sum is 0
- 4 Values whose Sum is 0
- 1152 - 4 Values whose Sum is 0
- 1152 - 4 Values whose Sum is 0
- UVA1152-4 Values whose Sum is 0
- POJ2785 4 Values whose Sum is 0
- nodejs(数据查询功能4)
- iOS 百度地图 轨迹记录 道路贴合
- session标签实例:简单的系统登录代码(巧妙地避开SQL注入攻击)
- search_n
- 修改tomcat编码格式
- 【高效算法设计-中途相遇法】4 Values whose Sum is 0 哈希表
- 找单向链表中离尾节点长度为n的节点
- Intent跳转工具类
- ASP.NET MVC:窗体身份验证及角色权限管理示例
- 第4章1节《MonkeyRunner源码剖析》ADB协议及服务: ADB协议概览OVERVIEW.TXT翻译参考(原创)
- Debug和Release区别
- 软件系统设计思路
- python模拟新浪微博登陆功能(新浪微博爬虫)
- 罗马字母发音表