51Nod-1267 题解
4个数和为0
题目大意
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0
Time: 1000 ms
Memory: 131072 kB
解题思路及分析
二分,灵感来源于之前二分的入门题
Ai+Bj=X
,Ai+Bj+Ck=X
定义一个新的数组b,数组的元素为
a[i] + a[j]
这样只需要b中取出2个数使得
b[i] + b[j] = 0
最开始WA了一发,注意不能有重复元素,判断一下即可
我的方法是加一个index数组,储存b[i]在a数组中对应的下标
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long llong;
const int N = 1e3 + 5;
llong a[N];
llong b[N * N];
int index[2][N * N];
int bsearch(llong a[], int n, int x)
{
int l = 0, r = n;
while (l <= r)
{
int mid = (l + r) / 2;
if (a[mid] == x)
{
return mid;
}
else if (a[mid] < x)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return -1;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%lld", &a[i]);
}
int sz = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
index[0][sz] = i;
index[1][sz] = j;
b[sz++] = a[i] + a[j];
}
}
sort(b, b + sz);
int ans = -1;
for (int i = 0; i < sz; i++)
{
ans = bsearch(b, sz, -b[i]);
if (ans != -1)
{
bool f = true;
int c[10];
c[0] = index[0][i];
c[1] = index[1][i];
c[2] = index[0][ans];
c[3] = index[1][ans];
for (int j = 0; j < 4 && f; j++)
{
for (int k = j + 1; k < 4 && f; k++)
{
if (c[j] == c[k])
{
f = 0;
}
}
}
if (f)
{
printf("Yes\n");
break;
}
}
}
if (ans == -1) printf("No\n");
return 0;
}