二分法实例

本篇讲述关于二分法(算法)的实例应用(较为复杂的抽签问题)

题目:朋友将写有数字的n个纸片放入口袋中,你可以从口袋中抽取4次纸片,每次抽取后记录下数字并将其放回口袋中,如果这4个数字的数字的和为m;就是你赢,否则就是你朋友赢。现在只要存在抽取4张卡片之和为m的方案,我们就输出Yes,否则输出NO.1= 1= 输入为n=3,m=10,k={1,3,5};输出Yes;
样例2输入为n=3,m=9,k={1,3,5} ;输出为No

#include        /*二分搜索法(复杂度为O(n)*O(log2n))(即将数组先排序然后二分法查找)*/
int search(int *a,int n,int x); 

int search(int *a,int n,int x)//(a为要排序的数组,n为数组元素的个数,x为要查找的元素)
{
    int i=1,k=0,j=0,c,flag=0;
    for(i=1;i<n;i++)/*首先需要将数组进行排序*/
    {
        for(j=0;j<=n-i-1;j++)
        {
            if(a[i]>a[i+1]){k=a[i+1];a[i+1]=a[i];a[i]=k;}
            else {continue;}
        }
    }
    for(flag=0,j=0;j<n;j++)//二分法查找元素,每次循环都缩小了搜索范围1.1/2,1/4,'''1/(2)的j次方
    {
        c=(n+1)/2;//首先看中间的元素是否为我们要找的x
        if(a[c]==x) {flag=1;return flag;}//如果相等的话,我们即可返回return 1
        else if(a[c]<x) {j=c+1;}//如果x大于该数,则将范围变为C+1到n-1
        else {n=c;}//否则x小于等于该数,则将该数的范围变为0到c
    }
    return flag;//只要能够出循环,说明此区间不存在该搜索数
}
int main()
{
    int team[100],n,m;
    int a=0,b=0,c=0;
    int flag=0,i=0,x;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        flag=0;
        for(i=0;i<n;i++)
        {
            scanf("%d",&team[i]);
        }
        for(a=0;a<n;a++)
        {
            for(b=0;b<n;b++)
            {
                for(c=0;c<n;c++)
                {
                    x=m-team[a]-team[b]-team[c];
                    if(search(team,n,x)==1) {flag=1;break;}
                }
            }
        }
        if(flag==1) {printf("Yes\n");}
        else printf("No\n");
    };
    return 0;
}
至此我们便可解决此问题

对您有帮助的话点个赞吧

你可能感兴趣的:(ACM,C语言)