poj 2785 4 Values whose Sum is 0

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 -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列数,前两列分一组,后两列分一组。把第一列每个数和第二列每个数相加形成一个新的数组apb[n*n],把第三列每个数和第四列每个数相加形成数组cpd[n*n],把apb[ ]进行从小到大排序。从cpd[ ]的第一个数开始二分查找apb[ ]中有没有符合相加之和为0的。

注意:

1.注意2^28用int就足够了。

2. 排序之后可能有值相同的情况,所以当apb[ ]+cpd[ ]=0的时候要考虑apb数组中当前位置下的前面数和后面的数是否同样满足满足apb[ ]+cpd[ ]=0。

3.mid+1/-1。eg 当前mid=4;high=5.下一步要让mid=5,但是因为mid low high都是整型,所以下一步mid=(4+5)/2还是4,这样就死循环了,所以mid要为4+1。

 

源代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int a[4010],b[4010],c[4010],d[4010];
 4 int apb[4000*4000+10],cpd[4000*4000+10];
 5 int cmp(void const *a,void const *b)
 6 {
 7     return ((*(int *)a>*(int *)b)?1:-1);
 8 }
 9 int main()
10 {
11     int n,i,j,low,high,mid,ans,k;
12     scanf("%d",&n);
13     for(i=0; i<n; i++)
14         scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
15     for(i=0; i<n; i++)
16     {
17         for(j=0; j<n; j++)
18         {
19             apb[i*n+j]=a[i]+b[j];
20             cpd[i*n+j]=c[i]+d[j];
21         }
22     }
23     qsort(apb,n*n,sizeof(int),cmp);
24     for(i=0; i<n*n; i++)
25                ans=0;
26     for(i=0; i<n*n; i++)
27     {
28         high=n*n-1;
29         low=0;
30         mid=(high+low)/2;
31         while(low<high)
32         {
33              if(cpd[i]+apb[mid]>0)
34                 high=mid-1;
35             else if(cpd[i]+apb[mid]<0)
36                 low=mid+1;
37             mid=(high+low)/2;
38             if(cpd[i]+apb[mid]==0)
39             {
40                 ans++;
41                 for(k=mid-1; k>=0; k--)
42                 {
43                     if(apb[k]+cpd[i]==0)
44                         ans++;
45                     else break;
46                 }
47                 for(k=mid+1; k<n*n; k++)
48                 {
49                     if(apb[k]+cpd[i]==0)
50                         ans++;
51                     else break;
52                 } break;
53             }
54         }
55     }
56     printf("%d\n",ans);
57     return 0;
58 }
59  

 

posted @ 2013-08-06 00:58  小の泽  阅读(150)  评论(0)    收藏  举报