我觉得这一题方法很好的,但是之前完全没有碰到过,也没有想到,这么简单直接降低复杂度的方法
先将两个集合合并成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 "); else printf("No "); } return 0; }