51Nod 1267 4个数和为0 ( 二分

来源:互联网 发布:用户画像常用算法 编辑:程序博客网 时间:2024/05/16 11:15

1267 4个数和为0

Description

给出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”。

Sample Input

5
-1
1
-5
2
4

Sample Output

Yes

题意

从数组中找来4个数字进行判断相加是否为0

题解:

暴力肯定是不行的n^3就GG了
这里就发现一个特别好的思路,将一个数组内的数字两两相加(不重复)存起来 然后在排序1e6个数 用二分查找 记住标记下相加之前时的位置 就可以了

AC代码

#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#include <iostream>#include <vector>#include <algorithm>using namespace std;#define ll long longconst int mod = 1e9+7;const int N = 1010;int arr[N];struct node {    int x, y;    int sum;}p[N*N];bool cmp(node x, node y){    return x.sum < y.sum;}int main(){    int n;    bool flag = false;    scanf("%d",&n);    for(int i = 0; i < n; i++)        scanf("%d",&arr[i]);    int k = 0;    sort(arr,arr+n);     for(int i = 0;i < n; i++) {    //使数组内的任意两个数相加且不重复         for(int j = i+1;j < n; j++) {            p[k].x = i;                  //标记每两个相加过的数字             p[k].y = j;            p[k++].sum = arr[i] + arr[j];        }    }    sort(p,p+k,cmp);                    int low = 0, top = k-1;                             while(low < top) {        if(p[low].sum+p[top].sum==0&&p[low].x!=p[top].x && p[low].x!=p[top].y && p[low].y!=p[top].x && p[low].y!=p[top].y) {  //判断数字自身是否重复想加             flag = true; break;         }        else if(p[low].sum+p[top].sum< 0) low++;        else top--;     }    if(flag) puts("Yes");    else puts("No"); return 0;}
0 0
原创粉丝点击