[CF1698C]3SUM Closure
做题时间:2022.6.29
\(【题目描述】\)
给你 \(t(t\leq 1000)\) 个长度为 \(n(\sum n\leq 2\times 10^5)\) 的序列 \(a\) 。判断每一个序列是否满足 \(\forall i,j,k\) , \(1\leq i<j<k\leq n\) ,存在 \(l(1\leq l\leq n)\) 满足 \(a_i+a_j+a_k=a_l\)
\(【输入格式】\)
第一行一个 \(t\)
接下来 \(2t\) 行,每组数据第一行一个整数 \(N\) ,第二行 \(N\) 个整数表示 \(a\)
\(【输出格式】\)
对于每一组数据一个 \(YES\) 或 \(NO\)
\(【考点】\)
分类讨论
\(【做法】\)
sb分类讨论
首先可以看得出来,若正数或负数过多,就会出现越加越多(少)的情况,不可能满足。经过验证可以发现,若正数或负数的个数必须 \(\leq2\)
好像可以暴力,但可能还有很多的0,考虑到0的个数太多对于结果并没有影响,当0的个数大于2时,和等于2的效果相同。
这样一来序列长度就控制在了 \(6\) 以内,直接暴力。
\(【代码】\)
#include<cstdio>
using namespace std;
const int N=2e5+50;
int a[N],n,t;
int b[N],ed;
bool Check()
{
int neg=0,pos=0,zer=0;
ed=0;
for(int i=1;i<=n;i++){
pos+=(a[i]>0),neg+=(a[i]<0),zer+=(a[i]==0);
if(a[i]!=0) b[++ed]=a[i];
}
if(neg>2||pos>2) return false;//正数或负数的个数>2不符合要求
if(zer>=1) b[++ed]=0;
if(zer>=2) b[++ed]=0;
//暴力
for(int i=1;i<=ed;i++){
for(int j=i+1;j<=ed;j++){
for(int k=j+1;k<=ed;k++){
int t=b[i]+b[j]+b[k];
bool q=false;
for(int l=1;l<=ed;l++){
if(t==b[l]){q=true;break;}
}
if(!q) return false;
}
}
}
return true;
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
if(Check()) printf("YES\n");
else printf("NO\n");
}
return 0;
}

浙公网安备 33010602011771号