4 Values whose Sum is 0(二分)

              4 Values whose Sum is 0

Time Limit: 15000MS   Memory Limit: 228000K
Total Submissions: 21370   Accepted: 6428
Case 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 -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).

Source

Southwestern Europe 2005

 

// 题意: 比如例子 6 行,每行 4 个数,从第一,二,三,四列各选一个数,要使和为 0 ,有几种组合?

n 最大有4000,但还是可以暴力,加二分

a + b = -( c + d )

枚举 a + b ,对于 c + d ,枚举一次,用一个大数组保存和,sort ,就可以二分了。要注意的是,二分到了要对左右继续搜索一下,不同的位置代表有不同的组合 

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 int n;
 9 int k;
10 
11 int num[4002][4];
12 int s[16000005];
13 
14 int erfen(int t)
15 {
16     int l=0,r=k-1;
17     while (l<=r)
18     {
19         int mid=(l+r)/2;
20         if (s[mid]==t)
21         {
22             int e = mid-1;
23             int  all=1;
24             while (e>=0&&s[e]==t)
25                 e--,all++;
26             e=mid+1;
27             while (e<k&&s[e]==t)
28                 e++,all++;
29             return all;
30         }
31         else if (s[mid]>t)
32             r=mid-1;
33         else
34             l=mid+1;
35     }
36     return 0;
37 }
38 
39 int main()
40 {
41     while (scanf("%d",&n)!=EOF)
42     {
43         for (int i=0;i<n;i++)
44             scanf("%d%d%d%d",&num[i][0],&num[i][1],&num[i][2],&num[i][3]);
45         k=0;
46         for (int i=0;i<n;i++)
47             for (int j=0;j<n;j++)
48             s[k++]=-(num[i][2]+num[j][3]);
49         sort(s,s+k);
50         int total=0;
51         for (int i=0;i<n;i++)
52         {
53             for (int j=0;j<n;j++)
54             {
55                 int left=num[i][0]+num[j][1];
56                 total+=erfen(left);
57             }
58         }
59         printf("%d\n",total);
60     }
61     return 0;
62 }
View Code

 

 

 

posted @ 2017-03-12 21:46  happy_codes  阅读(170)  评论(0编辑  收藏  举报