题目
解析
牌的数量增加到了1000,因此如果使用四个for
循环,肯定会超时,当n=1000
时,我们的时间复杂度就是n^4^
,肯定寄了,所以我们要对代码进行优化,想想看能不能减少一个for()
,因此我们发现可以把最内层的for
换成查找,这里的查找用的是二分查找,时间复杂度为logn
,这样一来时间复杂度就变成了n3logn,一下子快了不少,但是这样交上去还是有问题,我们还要更快,因此,我们可以再淦掉一个for
循环,因为4层for
循环,内两层for
循环就是用来查找是否有值等于m-x[i]-x[j]
,我们可以事先把内两层循环可能产生的值枚举出来,然后再配合二分查找,把时间复杂度降低到n2logn,这样就能AC了。
二分查找其实不用自己写,头文件<algorithm>中就包含了
binary_search(Begin_Iterator,End_Iterator,key)
当然了,自己写也没什么问题
二分查找
bool Binary_search(int *x,int i,int j,int key){
sort(x,x+n);//对数组排序
while(i<=j){
int p=(i+j)/2;
if(x[p]>key){
j=p-1;
}else if(x[p]<key){
i=p+1;
}else{
return true;
}
}
return false;
}
AC代码
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
int n,m;
scanf("%d %d",&n,&m);
const int MAX_SIZE=1010;
int x[MAX_SIZE];
for(int ix=0;ix<n;++ix){
scanf("%d",&x[ix]);
}
//产生枚举
vector<int>xx;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
xx.push_back(x[i]+x[j]);
}
}
//二分查找前先排序
sort(xx.begin(),xx.end());
//两轮搜查+二分查找
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
int key=m-x[i]-x[j];
if(binary_search(xx.begin(),xx.end(),key)){
puts("Yes");
return 0;
}
}
}
puts("No");
return 0;
}