Poj 2785 4 Values whose Sum is 0【二分查找】

来源:互联网 发布:网络远程教育在哪报名 编辑:程序博客网 时间:2024/05/21 18:46

4 Values whose Sum is 0
Time Limit: 15000MS Memory Limit: 228000KTotal Submissions: 18844 Accepted: 5606Case 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).

跟很久以前的一道抽签题目一样,减小时间复杂度,可以用折半查找的方法,另外二分查找的手动实现也是不太好写的吗,就当复习一下吧!


调用库函数!

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=4005;int a[maxn],b[maxn],c[maxn],d[maxn],sum[maxn*maxn];int upper(int s[],int l,int r,int x){int mid;while(l<r){mid=(l+r)>>1;if(x>=s[mid]){l=mid+1;}else{r=mid;}}return r;}int lower(int s[],int l,int r,int x){int mid;while(l<r){mid=(l+r)>>1;if(x>s[mid]){l=mid+1;}else{r=mid;}}return l;}long long slove(int n){int cnt=0;for(int i=0;i<n;++i){for(int j=0;j<n;++j){sum[cnt++]=a[i]+b[j];}}sort(sum,sum+cnt);long long ans=0;for(int i=0;i<n;++i){for(int j=0;j<n;++j){int tp=upper(sum,0,cnt,-(c[i]+d[j]))-lower(sum,0,cnt,-(c[i]+d[j]));//这里返回的是符合条件的元素个数 ans+=tp;}}return ans;}int main(){int n;//freopen("shuju.txt","r",stdin);while(~scanf("%d",&n)){for(int i=0;i<n;++i){scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);}printf("%d\n",slove(n));}return 0;}


手动实现两种二分函数


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=4005;int a[maxn],b[maxn],c[maxn],d[maxn],sum[maxn*maxn];int upper(int s[],int l,int r,int x){int mid;while(l<r){mid=(l+r)>>1;if(x>=s[mid])//逼近最右端的等于自己的位置{l=mid+1;}else{r=mid;}}return r;//注意返回}int lower(int s[],int l,int r,int x){int mid;while(l<r){mid=(l+r)>>1;if(x>s[mid])//逼近最左端等于自己的位置{l=mid+1;}else{r=mid;}}return l;}long long slove(int n){int cnt=0;for(int i=0;i<n;++i){for(int j=0;j<n;++j){sum[cnt++]=a[i]+b[j];}}sort(sum,sum+cnt);long long ans=0;for(int i=0;i<n;++i){for(int j=0;j<n;++j){int tp=upper(sum,0,cnt,-(c[i]+d[j]))-lower(sum,0,cnt,-(c[i]+d[j]));//符合条件的元素个数 ans+=tp;}}return ans;}int main(){int n;//freopen("shuju.txt","r",stdin);while(~scanf("%d",&n)){for(int i=0;i<n;++i){scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);}printf("%d\n",slove(n));}return 0;}



0 0
原创粉丝点击