二分查找

基本思路

基本思路就是左边界右边界,注意特殊情况,然后如果猜大了就把右边界设置为猜的-1,小了左边界为其+1即可。
AcWing 789. 数的范围

#include<stdio.h>


void query(int P[100100], int k, int n){
    int l,r,p,f;
    f=0;
    l = 0, r = n-1;
    while(l<=r){//边界条件是l不大于r
        p = (l+r)>>1;
        if(P[p]<k){
            l = p+1;//更新边界的方式是不要带上p,直接收缩
        }else if(P[p]>k){
            r = p-1;//同上
        }else{
            f=1;
            break;
        }
    }
    if(f==0){
        printf("-1 -1\n");
        return;
    }

    //找边界也要二分,神人,从0和最大二分呗
    //找左边界,性质是p+1是另一个
    int left, right;
    l = 0, r = p;
    while(l<=r){
        left = (l+r)>>1;
        if(P[left]<P[p]){
            l = left+1;
        }else if(P[left-1]==P[p]){
            r = left - 1;
        }else{
            break;
        }
    }
    l = p, r = n - 1;
    while(l<=r){
        right = (l+r)>>1;
        if(P[right+1]==P[p]){
            l = right+1;
        }else if(P[right]>P[p]){
            r = right-1;
        }else{
            break;
        }
    }    
    printf("%d %d\n",left,right);
    return;
}

int main(){
    int n,q,P[100100],K[10010];
    scanf("%d %d",&n,&q);
    for(int i = 0; i < n; i++)scanf("%d",&P[i]);
    for(int i = 0; i < q; i++)scanf("%d",&K[i]);
    for(int i = 0; i < q; i++)query(P,K[i],n);
    return 0;
}

AcWing 790. 数的三次方根

#include<stdio.h>

void get(double n){
    double l,r,p,x;
    if(n>1){
        l = 0, r = n;
    }else if(n < -1){
        l = n, r = 0;
    }else if(n>0&&n<1){
        l = 0, r = 1;
    }else if(n<0&&n>-1){
        l = -1, r = 0;
    }
    while(l<=r){
        p = (l+r)/2;
        x = p*p*p;
        if(x>n){
            r = p - 0.0000001;
        }else if(x<n){
            l = p + 0.0000001;
        }else{
            break;
        }
    }    
    printf("%.6f",p);
}

int main(){
    double n;
    scanf("%lf",&n);
    get(n);
    return 0;
}
posted @ 2025-05-10 22:35  .N1nEmAn  阅读(23)  评论(0)    收藏  举报