你的朋友提议玩一个游戏,将写有数字的N个纸片放入口袋中,你可以从口袋中抽取4次纸片,每次记下纸片数字后将其放回口袋中。如果这四个数字的和是m,就是你赢,否则的话就是你朋友赢,你挑战了好几回,结果一次也没有赢过,于是怒而撕破口袋,取出所有纸片,检查自己是否有赢的可能性。请你编写一个一个程序,判断纸片上所写的数字是a1,a2,a3,,,,an,是否存在抽取和为m的方案,如果存在,输出YES,否则的话,输出NO。
限制条件
1<=n<=50
1<=m<=100000000
1<ai<100000000
样例1:
输入:
n=3
m=10
a={1,3,5}
输出:
YES
样例二:
输入:
n=3
m=9
a={1,3,5}
输出:
NO
分析:如果n的值为50,四层循环的时间的复杂度还不是很大,如果n=1000四层循环就会超时,所以有第二种和第三种方法,用的是二分查找法
第一种方法:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
int n,m;
int a[100];
while(cin>>n>>m)
{
bool flag=false;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
for(int l=0;l<n;l++)
{
if(a[i]+a[j]+a[k]+a[l]==m)
flag=true;
}
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
第二种方法:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
bool binary_search(int *a,int len,int goal)
{
int low=0;
int high=len-1;
while(low<=high)
{
int mid=(low+high)/2;
if(a[mid]==goal)
return true;
else if(a[mid]>goal)
high=mid-1;
else
low=mid+1;
}
}
int main()
{
int n,m;
int a[1010];
while(cin>>n>>m)
{
bool flag=false;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
{
if(binary_search(a,n,m-a[i]-a[j]-a[k]))
flag=true;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
第三种方法:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
bool binary_search(int *b,int len,int goal)
{
int low=0;
int high=len-1;
while(low<=high)
{
int mid=(low+high)/2;
if(b[mid]==goal)
return true;
else if(b[mid]>goal)
high=mid-1;
else
low=mid+1;
}
}
int main()
{
int n,m;
int a[100],b[100];
while(cin>>n>>m)
{
bool flag=false;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
int count=0;
for(int k=0;k<n;k++)
for(int l=0;l<n;l++)
{
b[count++]=a[k]+a[l];
}
sort(b,b+count);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(binary_search(b,count,m-a[i]-a[j]))
flag=true;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}