3 3 31 2 31 2 31 2 331410Sample OutputCase 1:NOYESNO
n三次方的复杂度会超时。
三个数组,把第一个和第二个数组组合起来,构成sum数组保存所有和的可能(有重复无所谓),然后再在sum数组中
二分根据 sum[i]+c[j]=X,在sum数组二分X-c[j]的值,一旦某一个j找到一个对应的sum[i],就YES。时间复杂度下降
为n^2+nlogn
#include <iostream>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <algorithm>#include <vector>#include <string>#include <cstring>#include <sstream>#define INF 100000000using namespace std;int L,N,M,S;int a[505];int b[505];int c[505];int sum[250005];int k;int x;int tmp;int main(){ int kase=1; while(scanf("%d%d%d",&L,&N,&M)==3) { for(int i=0;i<L;i++) { scanf("%d",&a[i]); } for(int i=0;i<N;i++) { scanf("%d",&b[i]); } for(int i=0;i<M;i++) { scanf("%d",&c[i]); } k=0; for(int i=0;i<L;i++) { for(int j=0;j<N;j++) { sum[k++]=a[i]+b[j]; } } sort(sum,sum+k); scanf("%d",&S); printf("Case %d:/n",kase++); while(S--) { scanf("%d",&x); int flag=0; for(int j=0;j<M;j++) { tmp=x-c[j]; int left=0,right=k-1; int mid; while(left<=right) { mid=(left+right)/2; if(sum[mid]>tmp) { right=mid-1; } else if(sum[mid]<tmp) { left=mid+1; } else { flag=1; break; } } if(sum[left]==tmp&&left<k || sum[right]==tmp&&right>=0) { flag=1; } if(flag==1) { printf("YES/n"); break; } } if(flag==0) { printf("NO/n"); } } } return 0;}
新闻热点
疑难解答