4 Values whose Sum is 0 (二分)

 思路:分治法

 枚举4组数O(n^4)绝对超时

 因此可以使用分治的思想,将 4 组数分为两组,然后每组再分别计算和,最后对两组合进行排序,让正数与负数相加判断是否为 0 即可

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 int a[4001];
 9 int b[4001];
10 int c[4001];
11 int d[4001]; 
12 int n;
13 int s1[20000000];
14 int s2[20000000];
15 
16 int main()
17 {
18     while(scanf("%d", &n) != EOF)
19     {
20         for(int i = 1; i <=n; ++i)
21             scanf("%d %d %d %d", &a[i], &b[i], &c[i], &d[i]);
22         
23         int k = 1;
24         for(int i = 1; i <= n; ++i)
25         {
26             for(int j = 1; j <= n; ++j)
27             {
28                 s1[k] = a[i] + b[j];
29                 s2[k] = c[i] + d[j];
30                 ++k;
31             }
32         }
33         
34         sort(s1+1, s1+k);
35         sort(s2+1, s2+k);
36         
37         int right = k - 1;
38         int ans = 0;
39         for(int left = 1; left < k; ++left)
40         {
41             while(right > 0 && s1[left] + s2[right] > 0)
42                 right--;
43                 
44             if(right < 0)
45                 break;
46                 
47             int tmp = right;    // 一组left可能对应多组right解 
48             while(right > 0 && s1[left] + s2[right] == 0)
49             {
50                 ans++;
51                 right--;
52             }    
53             right = tmp;        // 下一组left可能和当前这一组left相同,所以rigiht要复原 
54         }
55         
56         printf("%d
", ans);
57     }
58     
59 
60     return 0;
61 }
原文地址:https://www.cnblogs.com/FengZeng666/p/11286555.html