题目网址点击打开链接
题目大意就是给你5个数组a,b,c,d,e;然后问你是否存在ai+bj+ck+dn+em=0。
一开始我把5个数组分成了3和2,把后面2个数组合并为一个数组,然后用3个for遍历前面3个数组,然后再用二分找,结果超时了。后来看了题解是把5个数组分成了2,2,1的形式,a和b合成f数组,c和d合成g数组,然后遍历d数组的每一个数,找是否存在fi+gj==dk.不过这个不是简单的3个for来查找。而是用了2个指针初始时一个cnt1指向f数组最小的值,cnt2指向g数组最大的值,每次查找过程是这样的如果f[cnt1]+g[cnt2]==sum就结束了,如果f[cnt1]+g[cnt2]<sum,cnt1++,取f数组里更大的数,如果f[cnt1]+g[cnt2]>sum,cnt2--,取g数组里更大的数。
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long t,flag,k1,k2,cnt1,cnt2,n,sum;
cin>>t;
while(t--)
{
flag=0,k1=0,k2=0;
long long a[205],b[205],c[205],f[40000+10],g[40000+10];
cin>>n;
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
for(int i=0;i<n;i++)
scanf("%lld",&b[i]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
f[k1++]=a[i]+b[j];
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
for(int i=0;i<n;i++)
scanf("%lld",&b[i]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[k2++]=a[i]+b[j];
for(int i=0;i<n;i++)
scanf("%lld",&c[i]);
sort(f,f+k1);
sort(g,g+k2);
for(int i=0;i<n;i++)
{
flag=0;
sum=-c[i];
cnt1=0;
cnt2=k2-1;
while(cnt1<k1&&cnt2>=0)
{
if((f[cnt1]+g[cnt2])==sum)
{
flag=1;
break;
}
if(f[cnt1]+g[cnt2]<sum)
cnt1++;
else
cnt2--;
}
if(flag)
break;
}
if(flag)
printf("Yes
");
else
printf("No
");
}
return 0;
}