二分法算法

算法笔记看后所写!!!!

计算函数零点,当然,只能返回一个值

//计算函数的零点
#include <iostream>

using namespace std;
const double eps=1e-5;
double f(double x);
double x_zero(double l,double r);
int main()
{
    cout << x_zero(-5,10) << endl;
    return 0;
}

double f(double x)
{
    return x*x+3*x+1;
}

double x_zero(double l,double r)
{
    double mid;
    while(r-l>eps)
    {
        mid=l+(r-l)/2;
        if(f(mid)>f(l))
            r=mid;
        else
            l=mid;
    }
    return mid;
}

//装水问题,侧面看上去是一个半圆的储水装置,半圆的半径是R
//要往里面装入高度为h的水,要求测面看过去的面积s1与半圆面积s2
//的比例恰好为r,求h

//装水问题,侧面看上去是一个半圆的储水装置,半圆的半径是R
//要往里面装入高度为h的水,要求测面看过去的面积s1与半圆面积s2
//的比例恰好为r,求h

#include <iostream>
#include <cmath>
using namespace std;
const double PI=acos(-1.0);
const double eps=1e-5;
double f(double R,double h);
double binarysolve(double R,double r);

int main()
{
    double R,r;
    cin >> R >> r;
    cout << binarysolve(R,r) << endl;
}


double f(double R,double h)
{
    double alpha=2*acos((R-h)/R);
    double l=2*sqrt(R*R-(R-h)*(R-h));
    double s1=R*R*alpha/2-l*(R-h)/2;
    double s2=PI*R*R/2;
    return s1/s2;
}

double binarysolve(double R,double r)
{
    double left=0,right=R,mid;
    while(right-left>eps)
    {
        mid=(left+right)/2;
        if(f(R,mid)>r)
            right=mid;
        else
            left=mid;
    }
    return mid;
}

//木棒切割问题
//给出n根木棒,长度已知,把他们切割成k段长度是整数且相等的木棒,求最长长度

//木棒切割问题
//给出n根木棒,长度已知,把他们切割成k段长度是整数且相等的木棒,求最长长度
#include <iostream>
#include <algorithm>
using namespace std;
int binarysolve(int *a,int n,int k,int l,int r);
int main()
{
    int n;
    cout << "input nums of stave\n" ;   //stave  木棒
    cin >> n;
    int a[n];
    cout << "inupt length of every stave\n";
    for(int i=0;i<n;++i)
        cin >> a[i];
    sort(a,a+n);
    int k;
    cout << "输入切割得到的木棒数目\n";
    cin >> k;
    cout << binarysolve(a,n,k,0,a[n-1]) << endl;

}

int binarysolve(int *a,int n,int k,int l,int r)
{
    int mid=0;
    while(l<r)
    {
        mid=(l+r)/2;
        int ans=0;
        for(int i=0;i<n;++i)
            ans+=a[i]/mid;
        if(ans<k)
            r=mid;
        else
            l=mid+1;
    }
    return l-1;
}


区间不相交问题,给出N个开区间(x,y),从中选择极尽可能多的开区间,
使得这些开区间两两没有交集


//区间不相交问题,给出N个开区间(x,y),从中选择极尽可能多的开区间,
//使得这些开区间两两没有交集
#include <iostream>
#include <algorithm>
using namespace std;
struct coordinate   //coordinate :坐标
{
    int x,y;
};
bool cmp(coordinate a,coordinate b)
{
    if(a.x!=b.x)
        return a.x>b.x;
    else
        return a.y<b.y;
}

int main()
{
    int n;
    cout << "输入坐标个数:\n";
    cin >> n;
    coordinate a[n];
    cout << "输入各个坐标的值\n";
    for(int i=0;i<n;++i)
        cin >> a[i].x >> a[i].y;
    sort(a,a+n,cmp);
    int ans=1,lastX=a[0].x;
    for(int i=1;i<n;++i)
    {
        if(a[i].y<=lastX)
        {
            ++ans;
            lastX=a[i].x;
        }
    }
    cout << "开区间最大的个数\n";
    cout << ans << endl;
}

//当然,从左到右开始选择也可以,也是选择区间问题

//当然,从左到右开始选择也可以
#include <iostream>
#include <algorithm>
using namespace std;
struct coordinate   //coordinate :坐标
{
    int x,y;
};
bool cmp(coordinate a,coordinate b)
{
    if(a.y!=b.y)
        return a.y<b.y;
    else
        return a.x>b.x;
}

int main()
{
    int n;
    cout << "输入坐标个数:\n";
    cin >> n;
    coordinate a[n];
    cout << "输入各个坐标的值\n";
    for(int i=0;i<n;++i)
    {
        cin >> a[i].x >> a[i].y;
        while(a[i].x>=a[i].y)
        {
            cout << "输入正确的坐标:\n";
            cout << "您还需输入 " << n-i << " 个坐标\n";
            cin >> a[i].x >> a[i].y;
        }
    }
    sort(a,a+n,cmp);
    int ans=1,lastY=a[0].y;
    for(int i=1;i<n;++i)
    {
        if(a[i].x>=lastY)
        {
            ++ans;
            lastY=a[i].y;
        }
    }
    cout << "开区间最大的个数\n";
    cout << ans << endl;
}

6)返回第一个大于等于x的下标;

/**
    6)返回第一个大于等于x的下标;
    data:
    10
    1 5 5 8 8  11 12 12 12 15
    5
*/

/**
#include <iostream>
using namespace std;

int binarysolve(int *matr,int l,int r,int val);

int main()
{
    int n;
    cin >> n;
    int a[n];
    for(int i=0;i<n;++i)
        cin >> a[i];
    int val;
    cin >> val;
    int index = binarysolve(a,0,n-1,val);
    cout << index << endl;
    cout << a[index] << endl;
    return 0;
}

/// [l,r]分为[l,mid],[mid+1,r];
int binarysolve(int *matr,int l,int r,int val)
{
    int mid;
    while(l<r)
    {
       mid=(l+r) / 2;
       if(matr[mid]>=val)
            r=mid;
       else
            l=mid+1;
    }
    return l;
}
*/


    7)返回最后一个一个小于等于x的下标;

/**
    7)返回最后一个一个小于等于x的下标;
    data:
    10
    1 5 5 8 8  11 12 12 12 15
    5
*/

#include <iostream>
using namespace std;

int binarysolve(int *matr,int l,int r,int val);

int main()
{
    int n;
    cin >> n;
    int a[n];
    for(int i=0;i<n;++i)
        cin >> a[i];
    int val;
    cin >> val;
    int index = binarysolve(a,0,n-1,val);
    cout << index << endl;
    cout << a[index] << endl;
    return 0;
}

/// [l,r]分为[l,mid-1],[mid,r];
int binarysolve(int *matr,int l,int r,int val)
{
    int mid;
    while(l<r)
    {
       mid=(l+r +1) / 2; //mid必须加1;当r-l==1时,会造成死循环
       if(matr[mid]<=val)
            l=mid;
       else
            r=mid-1;
    }
    return l;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值