Pie--hdu1969(二分法)

二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。

二分法查找的思路如下:

(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。

(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。

(3)如果某一步数组为空,则表示找不到目标元素。
二分法查找的时间复杂度O(logn)。
首先对一个简单的数组进行实验一下 找到指定的key

#include <iostream>
#include <algorithm>
using namespace std;
int  arr[10]={1,5,6,3,2,8,9,7,4,10};
int binary_search (int star, int end, int key)
{
    int ret = -1;//未搜索到数据返回数据-1下标
    int mid;
    while(star<=end){
        mid=(star+end)/2;
        if(arr[mid]<key)
            star = mid+1;
        else if(arr[mid]>key)
            end = mid -1;
        else {
            ret = mid;
            break;
            }
        }
        return ret;//单一出口;
}
int main()
{
    sort(arr,arr+10);
    int result = binary_search(0,10,5);
    cout<<"要找的数据的下标为:    "<<result<<endl;
    return 0;
}

在这里插入图片描述
首先必须确保你要查找的数据是单调的,如果不是单调的需要进行排序,这里用了sort排序,前面博客已经介绍过,这里不在阐述 sort排序

接下来就说一说这道体现二分基础的简单题

题目链接 Pie–hdu1969(二分法)

题解:
给你n个蛋糕的半径,你有m个朋友,所以总共有m+1个人,现在要分蛋糕,要求每个人分到的大小都是一样的,且每个人的蛋糕都是从一块上切割下来的(不能是2个不同的蛋糕拼起来的),现在问每个人最多能分到多少蛋糕(体积),保留到小数点后4位输出。

AC代码:

#include<bits/stdc++.h>  //偷偷用了万能头文件   嘘......
using namespace std;
typedef long long int ll;
const int MAX=1e7+100;
double pi = acos(-1.0);  // //计算π的值,这样更精确
int n,m;
int i,j;
double maxx,maxv,r;
double s[10000];
bool check(double x)   //判断此时的mid(也就是每个人的蛋糕面积)是否满足条件
{
    int num=0;
    for(i=0;i<n;i++)
    {
        num+=int(s[i]/x);    //计算有多少块蛋糕大于此时的平均面积
    }
    if(num>=m)
        return 1;    //如果有这么多块面积分给所有人,则满足题意
    else
        return 0;
}
int main()
{
    int t;
    while(cin >>t)
    {
        while(t--)
        {
            maxx,maxv=0.0;  // 分别代表蛋糕总面积和每个人无条件下分到的最大的蛋糕
            cin >>n>>m;
            m+=1;    //不要忘记自己哟
            memset(s,0,sizeof(s));
            for(i=0;i<n;i++)
            {
                cin >>r;
                s[i]=r*r*pi;      //记录所有蛋糕的面积
                maxv+=s[i];    //先把蛋糕的面积总和求出来
            }
            maxx=maxv/m;        //每个人平均分到的最大蛋糕就是蛋糕总面积的平均值
            double mid,left=0.0,right=maxx;//面积从0到平均值二分
            while(right-left>1e-7)     //满足这个精度则跳出循环(不了解精度问题,模仿别人的写法)
            {
                mid=(left+right)/2;       //二分取中
                if(check(mid))         //如果此时的mid满足条件,则证明mid还可以取得大一点,则取后半段继续搜
                    left=mid;
                else
                    right=mid;         //若不满足,则蛋糕取大了,则取前半段继续搜
            }
            printf("%.4f\n",mid);
        }
    }
    return 0;
}


今天的博客就到此结束,刚开始已经写了一半了,电脑发热关机了 我***。不过还好 又写了一遍,继续。go again…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值