二分法:夹缝中求和
题目:https://ac.nowcoder.com/acm/contest/8997/D
import java.util.*;
public class Main{
static int[] a;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int x = in.nextInt();
int y = in.nextInt();
a = new int[n];
for(int i = 0; i<n; i++){
a[i] = in.nextInt();
}
Arrays.sort(a);
long result = 0;
for(int i=0; i<a.length - 2; i++){
long min = binarySearchMin(i+1, a.length, x-a[i]);
long max = binarySearchMax(i+1, a.length, y-a[i]);
result += max - min;
}
System.out.println(result);
}
private static int binarySearchMin(int begin, int end, int num){
int left = begin;
int right = end - 1;
int min = end;
while(left <= right){
int mid = (left + right) / 2;
if(a[mid] >= num){
min = mid;
right = mid - 1;
}else{
left = mid + 1;
}
}
return min;
}
private static int binarySearchMax(int begin, int end, int num){
int left = begin;
int right = end - 1;
int min = end;
while(left <= right){
int mid = (left + right) / 2;
if(a[mid] > num){
min = mid;
right = mid - 1;
}else{
left = mid + 1;
}
}
return min;
}
}首先看标题就知道,二分法,数据结构没有好好听,所以呢,做起来就非常的苦难了。再次复习时,也一定要再次复习二分法的方法,借鉴别人的代码时发现,我们要找出下界和上界,在找出这两个之后,还要考虑,这两个数是否有重复的,难点就在这里,我们要利用二分法找出下界最左边的数,以及上界最右边的数,别人的经验非常丰富,以至于自己看了半天(废话少说)。别的代码不多做解释,因为要自己在回来看的时候要再多多理解一下代码。方法名(开始,结束,关键数),那么每次方法开始,开始和结束都是一样的,只有关键数,找下界的关键数是用x-a[i],那么找上界的关键数是用y-a[i],这样很巧妙,至于为什么,反正我只学会了 二分查找(进阶的)。
private static int binarySearchMax(int begin, int end, int num){
int left = begin;
int right = end - 1;
int min = end;
while(left <= right){
int mid = (left + right) / 2;
if(a[mid] > num){
min = mid;
right = mid - 1;
}else{
left = mid + 1;
}
}
return min;
}二分查找(进阶):
以:1 1 1 2 2 2 3 3 4 4 4 5 6 7 7为例
首先找下界时,数组左右分别为begin和end,那么关键数为num,例如num=1时,开始循环,mid = 0+14,mid=7,也就是3,在循环之后呢,会来到left=a[0],right=a[1],那么这个时候mid=0,那么a[mid]就是最小最左边的数了。
寻找上界的时候,num=y-a[i],num=3,那么mid=7,此时不是最右边的上界,那么就开始循环,不大于num则左边+1,但是呢mid还是7,继续+1,那么mid=8,a[mid]=4,那么就大于了3,此时继续循环就可以一直进行到结束,而right都不动。


查看8道真题和解析