题目大意:
每次从n个数里抽取一个数记录后并放回,问是否存在抽取的四个数之和为m的情况。
解题思路:
当n<10的时候,直接枚举即可;当n<1000时,则需要进行优化,先将四个数分为俩俩之和,再对结果进行二分搜索。
下面的算法时间复杂度为O(n^2 log n)。
ac代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1005],b[1000005];
bool b_search(int x){
int l=0,r=n*n-1;
while(l<=r){
int mid=(r+l)/2;
if(b[mid]==x) return 1;
else if(b[mid]>x) r=mid-1;
else l=mid+1;
}
return 0;
}
void solve(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
b[i*n+j]=a[i]+a[j];
}
}
sort(b,b+n*n);
for(int i=0;i<n*n;i++){
if(b_search(m-b[i])){
cout<<"yes\n";
return ;
}
}
cout<<"no\n";
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
solve();
return 0;
}
using namespace std;
int n,m;
int a[1005],b[1000005];
bool b_search(int x){
int l=0,r=n*n-1;
while(l<=r){
int mid=(r+l)/2;
if(b[mid]==x) return 1;
else if(b[mid]>x) r=mid-1;
else l=mid+1;
}
return 0;
}
void solve(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
b[i*n+j]=a[i]+a[j];
}
}
sort(b,b+n*n);
for(int i=0;i<n*n;i++){
if(b_search(m-b[i])){
cout<<"yes\n";
return ;
}
}
cout<<"no\n";
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
solve();
return 0;
}