Can you find it?
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/10000 K (Java/Others)Total Submission(s): 18034 Accepted Submission(s): 4555
3 3 3 1 2 3 1 2 3 1 2 3 3 1 4 10
Case 1: NO YES NO排序加二分,想象成C=S-A-B;
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #include<ctype.h> #include<iostream> #include<string> #include<algorithm> #include<set> #include<vector> #include<queue> #include<map> #include<numeric> #include<stack> #include<list> const int INF=1<<30; const int inf=-(1<<30); const int MAX=100010; using namespace std; __int64 a[511],b[511],c[511]; int L,M,N,S,q; __int64 d[250010]; //数组中的元素相加可能超过int范围 ///??为什么这样错啊 //int ss(__int64 ans,int m,int n) ///m和n表示数组d的第一位和最后一位 //{ // if((m+n)/2==(m+n)&&ans!=a[m+n]) // return 0; // else if((m+n)/2==(m+n)&&ans==a[m+n]) // return 1; // if(ans>d[(m+n)/2]) // ss(ans,(m+n)/2,m+n); // else if(ans<d[(m+n)/2]) // ss(ans,0,(m+n)/2); //} ///必记 int ss(__int64 ans,int m,int n) ///m和n表示数组d的第一位和最后一位 { int mid; while(m<=n) { mid=(n+m)>>1; ///右移一位,相当于除以2 if(d[mid]==ans) return 1; else if(d[mid]>ans) n=mid-1; else if(d[mid]<ans) m=mid+1; } return 0; } int main() { int n,j=0; while(~scanf("%d%d%d",&L,&M,&N)) { for(int i=0; i<L; i++) scanf("%lld",&a[i]); for(int i=0; i<M; i++) scanf("%lld",&b[i]); for(int i=0; i<N; i++) scanf("%lld",&c[i]); sort(c,c+N); q=0; for(int i=0; i<L; i++) for(int j=0; j<M; j++) { d[q++]=a[i]+b[j]; } d[q]='\0'; sort(d,d+q); q=unique(d,d+q)-d; //对d数组内相邻的相同元素去重(因此之前需要排序) int n; scanf("%d",&S); printf("Case %d:\n",++j); while(S--) { scanf("%d",&n); if(n<(c[0]+d[0])||n>(c[N-1]+d[q-1])) { printf("NO\n"); continue; } else { int t=0; for(int i=0; i<N; i++) { __int64 ans=n-c[i]; if(ss(ans,0,q)) { t=1; break; } } if(t) printf("YES\n"); else printf("NO\n"); } } } return 0; }