给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
Input
第1行,1个数N,N为数组的长度(4 <= N <= 1000)
第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。
Input示例
5
-1
1
-5
2
4
Output示例
Yes
暴力+排序+二分
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; int a[1100]; int main() { //freopen("1.txt", "r", stdin); int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a+n); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) { int k, m, sum; k = j+1; m = n-1; while (k < m) { sum = a[i]+a[j]+a[k]+a[m]; if (sum < 0) { k++; } else if (sum > 0) { m--; } else { k++; m--; printf("Yes "); return 0; } } } printf("No "); return 0; }
还有个很好的思路,先把数组中任意两个数存起来,再从小到大排序,类似二分的思想从两头开始查找,是否满足sum1+sum2==0 并且两个坐标不重叠,每个点只选一次
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; int a[1100]; struct node { int x, y; int sum; }P[1100*1100]; int cmp(node a, node b) { return a.sum < b.sum; } int main() { freopen("1.txt", "r", stdin); int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); int k = 0; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) { P[k].x = a[i]; P[k].y = a[j]; P[k++].sum = a[i]+a[j]; } sort(P, P+k, cmp); int l = 0, r = k-1; int flag = 0; while (l < r) { if (P[l].sum+P[r].sum==0 && P[l].x!=P[r].x && P[l].y!=P[r].y && P[l].x!=P[r].y && P[l].y != P[r].x) { flag = 1; break; } else if (P[l].sum+P[r].sum < 0) l++; else r--; } if (flag) printf("Yes "); else printf("No "); return 0; }