0
点赞
收藏
分享

微信扫一扫

4 Values whose Sum is 0 (二分)

4 Values whose Sum is 0 (二分)_#include

 

 思路:分治法

 枚举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\n", ans);
57 }
58
59
60 return 0;
61 }

 


举报

相关推荐

0 条评论