51nod 1267 二分

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1267

1267 4个数和为0

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
给出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
将所有两个不同的数的和以及下标封入一个结构体里,然后按照和排序后循环对每一个和二分查找他的相反数的下标,找到一段待匹配的数据,只要相加为零且四个下标相互不冲突即表示可以。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<set>
 6 #include<ctime>
 7 #include<functional>
 8 #include<algorithm>
 9 using namespace std;
10 #define LL long long
11 int A[1005];
12 struct node 
13 { 
14     LL w; 
15     int  a, b; 
16     node() {};
17     node(LL s, int a, int b):w(s), a(a), b(b) {};
18     bool operator<(const node& tmp)const {
19         return w < tmp.w;
20     }
21 }P[1000005];
22 int main()
23 {
24     int N, i, j, k,p=0;
25     cin >> N;
26     for (i = 1;i <= N;++i)
27     {
28         scanf("%d", &A[i]);
29         for (j = 1;j < i;++j)
30         {
31             p++;
32             P[p].w = (LL)A[i] + A[j];
33             P[p].a = j;
34             P[p].b = i;
35         }
36     }
37     P[p + 1].w = 1e18;
38     bool ok = 0;
39     sort(P + 1, P + 1 + p);
40     for (i = 1;i <= p;++i)
41     {
42         int k = lower_bound(P+1,P+2+p,node(-P[i].w,0,0))-P;
43         if (P[k].w != -P[i].w) continue;
44         for (j = k;P[j].w == -P[i].w&&j <= p;j++) {
45             if (P[i].a!=P[j].a&&P[i].a!=P[j].b&&P[i].b!=P[j].a&&P[i].b!=P[j].b) { ok = 1;break; }
46         }
47         if (ok)break;
48     }
49     ok ? puts("Yes") : puts("No");
50     //system("pause");
51     return 0;
52 }

 

posted @ 2017-08-24 20:31  *zzq  阅读(154)  评论(0编辑  收藏  举报