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

浙公网安备 33010602011771号