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 2 28 ) 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 -46 26 -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).
题目意思就是在一个4*N的矩阵里面 不同的行找出相加为0的数量;
暴力搜索的话四重循环肯定是不行的,但是如果把他分成两部分来搜,复杂度就从n^4到了2*n^2 数据最大4000 所以完全不会超时
#include<iostream> #include<algorithm> #include<cmath> using namespace std; int a[4005],b[4005],c[4005],d[4005]; int ab[16000005],cd[16000005]; int main() { int n,k=0,l=0,count=0; cin>>n; for(int i=0;i<n;i++) cin>>a[i]>>b[i]>>c[i]>>d[i]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) ab[k++]=a[i]+b[j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cd[l++]=c[i]+d[j]; sort(ab,ab+k); sort(cd,cd+l); int x=n*n-1,num=0; for(int i=0;i<n*n;i++){ while(x>=0&&ab[i]+cd[x]>0) x--; if(x<0) break; num=x; while(ab[i]+cd[num]==0&&num>=0){ count++; num--; } } cout<<count<<endl; return 0; }
二分
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[4001],b[4001],c[4001],d[4001]; int ab[4000*4000+1],cd[4000*4000+1]; int k2; int check(int x) { int left=1,right=k2-1,mid; while (left<=right) { mid=(left+right)/2; if (x==cd[mid]) { int w=0,e=mid; while (x==cd[e]&&e<k2) e++,w++; e=mid-1; while (x==cd[e]&&e>0) e--,w++; return w; } else if (x<cd[mid]) right=mid-1; else left=mid+1; } return 0; } int main() { int t,i,j,q; while (~scanf("%d",&t)) { for (i=1;i<=t;i++) scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]); memset(ab,0,sizeof(ab)); memset(cd,0,sizeof(cd)); int k1=1,sum=0; k2=1; for (i=1;i<=t;i++) { for (j=1;j<=t;j++) { ab[k1++]=a[i]+b[j]; cd[k2++]=-(c[i]+d[j]); } } sort(cd+1,cd+k2); for (i=1;i<k1;i++) sum+=check(ab[i]); printf("%d\n",sum); } return 0; }