You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2023_04_4_week;
// 来自微众银行
// 给出两个长度均为n的数组
// A = { a1, a2, ... ,an }
// B = { b1, b2, ... ,bn }。
// 你需要求出其有多少个区间[L,R]满足:
// 数组A中下标在[L,R]中的元素之和在[La,Ra]之中
// 数组B中下标在[L,R]中的元素之和在[Lb,Rb]之中
// 输入
// 第一行有一个正整数N(1<=N<=100000),代表两个数组的长度。
// 第二行有N个非负整数范围在0到1000000000之间代表数组中的元素。
// 第三行有N个非负整数范围在0到1000000000之间代表数组中的元素。
// 第四行有4个整数La,Ra,Lb,Rb范围在0到10^18之间代表题目描述中的参数。
// 输出
// 输出一个整数,代表所求的答案。
public class Code05_ValidRangeBetweenTwoArrays {
// 暴力方法
// 为了测试
public static int nums1(int[] A, int[] B, int la, int ra, int lb, int rb) {
int n = A.length;
int ans = 0;
for (int l = 0; l < n; l++) {
for (int r = l; r < n; r++) {
int sumA = 0;
int sumB = 0;
for (int i = l; i <= r; i++) {
sumA += A[i];
sumB += B[i];
}
if (sumA >= la && sumA <= ra && sumB >= lb && sumB <= rb) {
ans++;
}
}
}
return ans;
}
// 正式方法
// 时间复杂度O(N)
public static int nums2(int[] A, int[] B, int la, int ra, int lb, int rb) {
int n = A.length;
int ans = 0;
int rightA1 = 0, sumA1 = 0, rightA2 = 0, sumA2 = 0, rightB1 = 0, sumB1 = 0, rightB2 = 0, sumB2 = 0;
for (int l = 0; l < n; l++) {
while (rightA1 < n && sumA1 + A[rightA1] < la) {
sumA1 += A[rightA1++];
}
while (rightA2 < n && sumA2 + A[rightA2] <= ra) {
sumA2 += A[rightA2++];
}
while (rightB1 < n && sumB1 + B[rightB1] < lb) {
sumB1 += B[rightB1++];
}
while (rightB2 < n && sumB2 + B[rightB2] <= rb) {
sumB2 += B[rightB2++];
}
int left = Math.max(rightA1, rightB1);
int right = Math.min(rightA2, rightB2);
if (left < right) {
ans += right - left;
}
if (rightA1 == l) {
rightA1++;
} else {
sumA1 -= A[l];
}
sumA2 -= A[l];
if (rightB1 == l) {
rightB1++;
} else {
sumB1 -= B[l];
}
sumB2 -= B[l];
}
return ans;
}
// 为了测试
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * v);
}
return ans;
}
// 为了测试
public static void main(String[] args) {
int N = 50;
int V = 100;
int testTimes = 10000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N);
int[] A = randomArray(n, V);
int[] B = randomArray(n, V);
int a = (int) (Math.random() * V);
int b = (int) (Math.random() * V);
int c = (int) (Math.random() * V);
int d = (int) (Math.random() * V);
int la = Math.min(a, b);
int ra = Math.max(a, b);
int lb = Math.min(c, d);
int rb = Math.max(c, d);
int ans1 = nums1(A, B, la, ra, lb, rb);
int ans2 = nums2(A, B, la, ra, lb, rb);
if (ans1 != ans2) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}