算法 【二分】BISHI87 [CQOI2010]扑克牌 思路 求解代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 public static void main(String[] args) throws IOException { // 使用BufferedReader读取输入,使用PrintWriter输出结果 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); // 读取第一行输入,分割为字符串数组 String[] strA = br.readLine().trim().split("\\s+"); int n = Integer.parseInt(strA[0]); long m = Long.parseLong(strA[1]); int[] c = new int[n]; // 创建大小为n的整型数组 // 读取第二行输入,分割为字符串数组 String[] strB = br.readLine().trim().split("\\s+"); // 将字符串数组转换为整型数组 for(int i=0;i<n;i++){ c[i]=Integer.parseInt(strB[i]); } // 初始化二分查找的边界和结果变量 long low = 0,high = 10000000000L; // 设置查找范围为0到100亿 long ans = 0; // 执行二分查找 while(low<=high){ long mid = low +((high-low)>>1); // 计算中间值,使用位运算优化 // 检查中间值是否满足条件 if(check(mid,n,m,c)){ ans = mid; // 如果满足条件,更新答案 low = mid+1; // 尝试更大的值 }else{ high = mid-1; // 如果不满足,尝试更小的值 } } // 输出最终结果 out.println(ans); // 刷新输出流 out.flush(); // 关闭输出流 out.close(); // 关闭输入流 br.close(); } private static boolean check(long x,int n,long m,int[] c){ long need = 0; // 需要添加的资源总量 for(int count:c){ // 遍历每种资源的当前数量 if(count<x){ // 如果当前资源数量小于目标数量 need +=(x-count); // 计算需要添加的资源数量 } } return need <= m&& need <=x; // 判断需要添加的资源总量是否不超过m和x }