试题描述
|
你的朋友提议玩一个游戏:将写有数字的n 个纸片放入口袋中,你可以从口袋中抽取4 次纸片,每次记下纸片上的数字后都将其放回口袋中。如果这4 个数字的和是m,就是你赢,否则就是你的朋友赢。你挑战了好几回,结果一次也没赢过,于是怒而撕破口袋,取出所有纸片,检查自己是否真的有赢的可能性。请你编写一个程序,判断当纸片上所写的数字是k1,k2, …, kn 时,是否存在抽取4 次和为m 的方案。 |
输入
|
第一行为两个整数n,m;第二行为n个整数k1,k2, …, kn 。
|
输出
|
如果存在,输出“Yes”;否则,输出“No”。
|
输入示例
|
3 10 1 3 5 |
输出示例
|
Yes
|
其他说明
|
1 ≤ n ≤ 50
1 ≤ m ≤ 10^8 1 ≤ ki ≤ 10^8 |
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10000;
int start = 0,n,m,k[maxn],kk[maxn*maxn];
int bin_search(int x){
int l = start,r = maxn*maxn - 1;
while(l != r){
int tmp = (l + r)/2;
if(kk[tmp] < x) l = tmp + 1;
else if(kk[tmp] > x) r = tmp - 1;
else return 1;
}
if(kk[l] == x) return 1;
else return 0;
}
void solve(){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&k[i]);
//枚举内层两张牌之和的所有可能情况
for(int c=0;c<n;c++){
for(int d=0;d<n;d++){
kk[c*n + d] = k[c] + k[d];
}
}
//为了表示方便写成枚举n2个数字
sort(kk,kk + n*n);
while(!kk[start]) start++;
int mark = 0;
for(int a=0;a<n;a++){
for(int b=0;b<n;b++){
if(bin_search(m-k[a]-k[b])) mark = 1;
}
}
if(mark) printf("%s","Yes");
else printf("%s","No");
}
int main(){
solve();
return 0;
}