二分算法个人总结c++

来源:互联网 发布:小程序授权登录源码 编辑:程序博客网 时间:2024/06/05 05:10

二分算是比较高效的算法,分为二分查找和二分答案

二分查找

在排好序的数组中查找所需元素的位置,单次查找复杂度(log2n)

思想就是比较自己的值和中间值的大小,比mid大就向右区间二分,比mid小就向左区间二分,直到自己的值和左端点的值相等。

洛谷p1918保龄球

代码

#include<iostream>#include<iomanip>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm> using namespace std;int n; int k=0;struct node{    int mark,ball;}a[100001];int cmp(node x,node y){    return x.ball<y.ball;}int erfen(int l,int r){    while(l<=r)    {        int mid=(l+r)/2;        if(k>a[mid].ball) l=mid+1;        else r=mid-1;    }    if(a[l].ball==k) cout<<a[l].mark<<endl;    else cout<<"0"<<endl;}int main(){    cin>>n;        for(int i=1;i<=n;++i)    {        cin>>a[i].ball;        a[i].mark=i;    }    sort(a+1,a+n+1,cmp);    int q;cin>>q;    for(int i=1;i<=q;++i)    {            k=0;        cin>>k;        erfen(1,n);    }    return 0;} 
二分答案

根据答案可以推出答案是否合理,一般题目关键字为最大值的最小或最小值的最大,每次判断二分的结果是否可以,如果可以存储并继续找更优的解,不可以就退一步找可以的解。

洛谷p1182数列分段

代码

#include<iostream>#include<iomanip>#include<cstdio>#include<cstring> #include<algorithm>using namespace std;int n,m,a[100001],mid;int maxx=0,all=0,ans;bool judge(int x){   int k=0,cnt=1;    for(int i=1;i<=n;++i)    {   k+=a[i];        if(k>x)        {            cnt++;            k=a[i];        }    }    if(cnt>m) return 0;    else return 1;}int main(){    cin>>n>>m;    for(int i=1;i<=n;++i)    {        cin>>a[i];        if(a[i]>maxx) maxx=a[i];        all+=a[i];    }    int l=maxx,r=all;    while(l<=r)    {        mid=(l+r)/2;        if(judge(mid)==1)        {            ans=mid;            r=mid-1;        }        else l=mid+1;    }    cout<<ans;    return 0;}