二分模板(数的范围)-Java版

二分模板(数的范围)-Java版_第1张图片

//二分模块,向左找和向右找
//先向左找,在找到的基础上再向右找
//向右找,找到的数是 <= x 的最大数,并不等于x
//向左找,找到的数是 >= x 的最小数,并不等于x
//关于为什么向右找的 mid = l + r + 1 >> 1
//比如最后剩下 i 和 i + 1两个数  (a[i + 1] 和a[i] 都 <= x)
//向右找的定义是找到 <= x 的最大数 此时 如果mid = (l + r >> 1) == i
//如果满足 a[mid] <= x  此时就把mid更新成i,这样的话如何怎么操作,mid都一直等于i,造成死循环
//如果把 mid == l + r + 1 >> 1  ,此时mid 更新成了i + 1,只剩一个数,便可退出循环

import java.io.*;

public class Main{
    static int n,q;     //n个数,q个询问
    static int N = 100010;
    //用于存储n个数
    static int[] a = new int[N];
    //输入输出较多,用BufferedReader和BufferedWriter
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        String[] init = in.readLine().split(" ");
        n = Integer.parseInt(init[0]);
        q = Integer.parseInt(init[1]);

        String[] data = in.readLine().split(" ");
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(data[i]);
        }

        while(q -- > 0) {
            //拿到询问
            int x = Integer.parseInt(in.readLine());
            //开始向做找
            int l = 0, r = n - 1;
            while (l < r) {
                int mid = l + r >> 1;
                if (a[mid] >= x) r = mid;
                else l = mid + 1;
            }
                //退出循环后找到的是>=x的某个值,不代表是x
                if (a[l] == x) {
                    out.write(l + " ");
                    //满足条件才能继续向右找
                    r = n - 1;
                    while (l < r) {
                        int mid = l + r + 1 >> 1;
                        if (a[mid] <= x) l = mid;
                        else r = mid - 1;
                    }
                    out.write(r + "\n");
                } else out.write("-1 -1\n");
            }

        in.close();
        out.flush();
    }
}

可以再看看浮点数二分:浮点数二分

你可能感兴趣的:(算法,算法,数据结构,java,蓝桥杯)