题目:每次从n个数里抽取一个数记录后并放回,问是否存在抽取的四个数之和为m的情况。
当n<10的时候,直接枚举即可;当n<1000时,则需要进行优化,先将四个数分为俩俩之和,再对结果进行二分搜索。
下面的算法时间复杂度为O(n^2 log n)。
#include <iostream> #include<algorithm> using namespace std; int n,m; int a[1005],b[1000005]; bool b_search(int x); void solve(); int main() { while(cin>>n>>m){ for(int i=0;i<n;i++){ cin>>a[i]; } solve(); } return 0; } 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; //debug //cout<<mid<<":"<<b[mid]<<","; } 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++){ //调用STL /* if(binary_search(b,b+n*n,m-b[i])){ cout<<"yes\n";return; }*/ if(b_search(m-b[i])){ cout<<"yes\n";return; } } cout<<"no\n"; }