版权声明:《学习技巧》每次使用单边大脑的时间不要太久,连续使用左边大脑30分钟就如同连续使用左臂30分钟一样,周期性的交换让大脑两侧能够轮流休息,左脑活动包括了循序渐进的工作,解决逻辑问题与分析,而右脑活动包括了隐喻,创造性思考,模式匹配和可视化。 https://blog.csdn.net/intmainhhh/article/details/82556572
你的朋友提议玩一个游戏:将写有数字的n个纸片放入口袋中,你可以从口袋中抽取4次纸片,每次记下纸片上的数字后都将其放回口袋中。如果这4个数字的和是m,就是你赢,否则就是你的朋友赢。
请你编写一个程序,判断当纸片上所写的数字是k1,k2,... ,kn时,是否存在抽取4次和为m的方案。如果存在,输出为Yes;否则,输出为No。
限制条件:
1<=n<=1000
1<=m<=10^8
1<=ki<=10^8
样例输入
3 10
1 3 5
第一行代表n,m,第二行代表ki
样例输出:
Yes
例如当4次抽取的结果是1,1,3,5,和就是10
算法知识:
在C++的STL里面有lower_bound()和upper_bound()两个二分搜索的函数,
如在a[maxn]中搜索出现x的最小下标;就可以直接lower_bound(a,a+maxn,x);
如在a[maxn]中搜索出现x的最大下标;就可以直接upper_bound(a,a+maxn,x);
重要的时二分思想
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3;
int k[maxn],n,m,kk[maxn*maxn];
bool binary_search(int x) {
int l=0;
int r=n*n;
while(l<r) {
int index=l+(r-l)/2;
if(kk[index]==x) return true;
else if(k[index]<x) l=index+1;
else r=index;
}
return false;
}
void solve() {
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
kk[i*n+j]=k[i]+k[j];
sort(kk,kk+n*n);
bool flag=false;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++) {
if(binary_search(m-k[i]-k[j]))
flag=true;
}
if(flag) puts("Yes");
else puts("No");
}
int main() {
cin>>n>>m;
for(int i=0; i<n; i++) {
cin>>k[i];
}
solve();
return 0;
}