4个数和为0 ----51Nod

 给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。 

Input

第1行,1个数N,N为数组的长度(4 <= N <= 1000)
第2 - N + 1行:Ai(-10^9 <= Ai
<= 10^9)

Output

如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。

Sample Input

5
-1
1
-5
2
4

Sample Output

Yes

思路:将两两相加的和存起来再进行二分查找使得map[t1].value+map[t2].value==0, 并且坐标不重叠。
这个思路很有用如果是求三个数的和也是类似的。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

int board[1005];
struct Node
{
    int x,y;
    int value;
} map[1000005];

bool cmp(struct Node a,struct Node b)
{
    return a.value < b.value;
}

int main()
{
    int N;
    scanf("%d",&N);
    for(int i=0 ; i<N ; i++)
    {
        scanf("%d",&board[i]);
    }
    int t = 0;
    for(int i=0 ; i<N ; i++)
    {
        for(int j=i+1 ; j<N ; j++)
        {
            map[t].value = board[i] + board[j];
            map[t].x = i;
            map[t++].y = j;
        }
    }
    sort(map,map+t,cmp);
    int t1 = 0;
    int t2 = t-1;
    int flag = 0;
    while(t1<t2)
    {
        if(map[t1].value + map[t2].value == 0)
        {
            if(map[t1].x!=map[t2].x && map[t1].x!=map[t2].y && map[t1].y!=map[t2].x && map[t1].y!=map[t2].y)
            {
                flag = 1;
                break;
            }
            else if(map[t1].value == map[t1+1].value)t1++;
            else if(map[t2].value == map[t2+1].value)t2--;
            else
            {
                t1++;
                t2--;
            }
        }
        else if(map[t1].value + map[t2].value < 0)t1++;
        else if(map[t1].value + map[t2].value > 0)t2--;
    }
    if(flag)printf("Yes\n");
    else printf("No\n");

    return 0;
}
posted @ 2018-01-26 15:02  Assassin_poi君  阅读(135)  评论(0编辑  收藏  举报