我觉得这一题方法很好的,但是之前完全没有碰到过,也没有想到,这么简单直接降低复杂度的方法
先将两个集合合并成1个集合,合并两个(s1,s2),即每个集合里n^2个数,还剩一个n个数的集合
这样还剩超时的
然后再优化,这个也想不到啊。。
sum=三个集合里面各取一个数,
小集合里面就直接枚举,
把两个大集合s1 s2从小到大排序,
一个里面从小到大开始枚举,一个里面从大到小开始枚举,
那么sum>0时,就把大的--
sum<0时,就把小的++
最后我被int64坑了一上午
#include<iostream>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std; __int64 s[6][205],s1[40005],s2[40005]; int main()
{
int n,t;
__int64 i,j,flag,k,l,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<5;i++)
{
for(j=0;j<n;j++)
scanf("%I64d",&s[i][j]);
}
for(i=0,k=0;i<n;i++)
{
for(j=0;j<n;j++,k++)
{
s1[k]=s[1][i]+s[0][j];
s2[k]=s[2][i]+s[3][j];
}
}
sort(s1,s1+k);
sort(s2,s2+k);
l=k-1;
for(i=0,flag=0;i<n;i++)
{
j=l;
k=0;
while(j>=0 && k<=l)
{
sum=(s1[j]+s2[k]+s[4][i]);
if(!sum)
{
flag=1;
break;
}
else if(sum>0) j--;
else k++;
}
if(flag) break;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}