传送门
2 2 1 -1 1 -1 1 -1 1 -1 1 -1 3 1 2 3 -1 -2 -3 4 5 6 -1 3 2 -4 -10 -1
No Yes
就是给定5个集合 让你判断是否这5个集合中的数 能够相加==0
解题思路:
就是两个两个集合 合并 排序,然后剩下一个集合跑, 还得去重(不去也行,去重循环少点),将重新组合后的3个集合,让没有合并的集合放在最外层循环,然后里边就是一个从前往后跑,一个从后往前跑,如果相加>0,那个降序排列的-1,如果<0,升序的加+1。
PS:其实我以为暴力是不行的 会超时,应该是数据不是很强吧 哈哈~ 最坏的情况是 200*200*200*50 = 4 * 10^8,反正这样就过了。。。还是得看看正解呀
My Code:
include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 4e4+5; LL a[205],b[205],c[205],d[205],e[205]; LL t1[MAXN],t2[MAXN]; int main() { int n, T; cin>>T; while(T--) { scanf("%d",&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++) scanf("%lld",&c[i]); for(int i=0; i<n; i++) scanf("%lld",&d[i]); for(int i=0; i<n; i++) scanf("%lld",&e[i]); int cnt1=0, cnt2=0; for(int i=0; i<n; i++) for(int j=0; j<n; j++) t1[cnt1++] = a[i] + b[j]; for(int i=0; i<n; i++) for(int j=0; j<n; j++) t2[cnt2++] = c[i] + d[j]; sort(t1,t1+cnt1); sort(t2,t2+cnt2); cnt1 = unique(t1,t1+cnt1)-t1; cnt2 = unique(t2,t2+cnt2)-t2; bool ok = 0; for(int i=0; i<n; i++) { for(int j=0,k=cnt2-1; j<cnt1&&k>=0;) { if(t1[j]+t2[k]+e[i] == 0) { ok = 1; break; } else if(t1[j]+t2[k]+e[i] > 0) k--; else j++; } if(ok) { puts("Yes"); break; } } if(!ok) puts("No"); } return 0; }