上海建网站价格友链申请
题目背景
出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
## 题目描述
给出一串正整数数列以及一个正整数 $C$,要求计算出所有满足 $A - B = C$ 的数对的个数(不同位置的数字一样的数对算不同的数对)。
## 输入格式
输入共两行。
第一行,两个正整数 $N,C$。
第二行,$N$ 个正整数,作为要求处理的那串数。
## 输出格式
一行,表示该串正整数中包含的满足 $A - B = C$ 的数对的个数。
## 输入输出样例 #1
### 输入 #1
```
4 1
1 1 2 3
```### 输出 #1
```
3
```## 说明/提示
对于 $75\%$ 的数据,$1 \leq N \leq 2000$。
对于 $100\%$ 的数据,$1 \leq N \leq 2 \times 10^5$,$0 \leq a_i <2^{30}$,$1 \leq C < 2^{30}$。
2017/4/29 新添数据两组
先想暴力搜索
import java.util.Scanner;
import java.util.Arrays;public class Main {private static int[] nums;private static int sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();int C = scan.nextInt();nums = new int[N];for (int i = 0; i < N; i++) {nums[i] = scan.nextInt();}Arrays.sort(nums);for (int i = nums.length - 1; i >= 0; i--) {for (int j = i - 1; j >= 0; j--) {if(nums[i] - nums[j] == C)sum ++;}}System.out.println(sum);}
}
一边使用二分
import java.util.Scanner;
import java.util.Arrays;public class Main {private static int[] nums;private static int C;private static int sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();int C = scan.nextInt();nums = new int[N + 1];for (int i = 1; i <= N; i++) {nums[i] = scan.nextInt();}Arrays.sort(nums);for (int i = nums.length - 1; i >= 0; i--) {binarySearch(0,i + 1,nums[i] - C);}System.out.println(sum);}private static void binarySearch(int left,int right,int tar) {if(tar < nums[1] || tar > nums[nums.length - 1])return;int rigB = right;int mid = 0;while(left + 1 < right) {mid = (left + right) / 2;if(isBlue(mid,tar))left = mid;elseright = mid;}if(nums[right] != tar)return;for (int i = right; i < rigB; i++) {if(nums[i] == tar)sum ++;}}private static boolean isBlue(int x,int tar) {return nums[x] < tar;}}
两边使用二分但是没有开long
import java.util.Scanner;
import java.util.Arrays;public class Main {private static int[] nums;private static int C;private static int sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();int C = scan.nextInt();nums = new int[N + 1];for (int i = 1; i <= N; i++) {nums[i] = scan.nextInt();}Arrays.sort(nums);for (int i = nums.length - 1; i >= 0; i--) {int leftB = binarySearch(0, i + 1, nums[i] - C);if (leftB == -1)continue;int rigB = binarySearch02(0,i + 1,nums[i] - C);sum += rigB - leftB + 1;}System.out.println(sum);}private static int binarySearch(int left, int right, int tar) {if (tar < nums[1] || tar > nums[nums.length - 1])return -1;int rigB = right;int mid = 0;while (left + 1 < right) {mid = (left + right) / 2;if (isBlue(mid, tar))left = mid;elseright = mid;}if (nums[right] == tar)return right;return -1;}private static int binarySearch02(int left, int right, int tar) {int mid = 0;while (left + 1 < right) {mid = (left + right) / 2;if (isRed(mid, tar))right = mid;elseleft = mid;}if(nums[left] == tar)return left;return -1;}private static boolean isBlue(int x, int tar) {return nums[x] < tar;}private static boolean isRed(int x, int tar) {return nums[x] > tar;}}
开了long之后过了
import java.util.Scanner;
import java.util.Arrays;public class Main {private static int[] nums;private static int C;private static long sum;public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();int C = scan.nextInt();nums = new int[N + 1];for (int i = 1; i <= N; i++) {nums[i] = scan.nextInt();}Arrays.sort(nums);for (int i = nums.length - 1; i >= 0; i--) {int leftB = binarySearch(0, i + 1, nums[i] - C);if (leftB == -1)continue;int rigB = binarySearch02(0,i + 1,nums[i] - C);sum += rigB - leftB + 1;}System.out.println(sum);}private static int binarySearch(int left, int right, int tar) {if (tar < nums[1] || tar > nums[nums.length - 1])return -1;int rigB = right;int mid = 0;while (left + 1 < right) {mid = (left + right) / 2;if (isBlue(mid, tar))left = mid;elseright = mid;}if (nums[right] == tar)return right;return -1;}private static int binarySearch02(int left, int right, int tar) {int mid = 0;while (left + 1 < right) {mid = (left + right) / 2;if (isRed(mid, tar))right = mid;elseleft = mid;}if(nums[left] == tar)return left;return -1;}private static boolean isBlue(int x, int tar) {return nums[x] < tar;}private static boolean isRed(int x, int tar) {return nums[x] > tar;}}
二分用不用还是依据时间复杂度来看的!
会二分发现那里不够用,可以用二分。把那个问题转化为二分问题
甚至可以进一步分析
找好的老师,这次找了——会code的小金鱼——几乎是马上就学会了二分!!!!!!!!!!
二分查找 | 妈妈再也不怕我写错二分啦 | 五点七边二分视频补充_哔哩哔哩_bilibili
二分查找为什么总是写错?_哔哩哔哩_bilibili
二分习题课 | 手把手教你二分答案! | 超级细不听血亏_哔哩哔哩_bilibili