1267 4个数和为0
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
收起
输入
第1行,1个数N,N为数组的长度(4 <= N <= 1000) 第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)输出
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。输入样例
5 -1 1 -5 2 4输出样例
Yes
思路:
4-sum问题,k-sum问题可以单独作为一个专题总结一下。
网上题解大部分说二分,哪里的二分,感觉有点像尺取的思路(2-SUM问题头尾指针法)?
对于序列a1、a2、a3、、、、an-1、an,最暴力的解法,四层循环枚举a数组,
考虑到枚举两层循环(枚举四个数的前两个数)后就是一个2-SUM问题,对于2-SUM问题,我们有头尾指针
的O(N)算法,所以总共时间复杂度O(N*N*N)。
另外看到一篇O(N*N+N)的题解,不过感觉其思路在处理重叠问题时有点小问题:
https://blog.csdn.net/h1021456873/article/details/49226563。
具体问题见评论。
代码实现:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+100;
int a[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
while(cin>>n)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;++i)cin>>a[i];
sort(a+1,a+1+n);
bool f=0;
for(int i=1;i<=n;++i)
{
for(int j=i+1;j<=n;++j)
{
LL tmp=-(a[i]+a[j]);
int l=j+1;
int r=n;
while(l<=r)
{
if(a[l]+a[r]==tmp)
{
f=1;
break;
}
else if(a[l]+a[r]<tmp)l++;
else r--;
}
if(f)break;
}
if(f)break;
}
if(f)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
The end;