一天一道算法题day02

这是问题的简单版。在这个版本中,唯一的不同仅仅在 m=1m=1 。

现在,给定两个数组 a1,a2,...,ana1​,a2​,...,an​ 和 b1,b2,...,bnb1​,b2​,...,bn​ 。在进行操作前,你可以按照你的想法对这个数组进行重新排序。之后,在每一轮操作中,若数组非空,你将会进行以下两个子操作:

  • 从 aa 数组中选择任意一个元素,删除它(剩余的所有元素将按照原来的相对顺序转移到一个新的 aa 数组),
  • 从 bb 数组中选择任意一个元素,删除它(剩余的所有元素将按照原来的相对顺序转移到一个新的 bb 数组)。

设 kk 为两个数组的最终长度。现在,你需要找到最小的操作次数,使得对于所有的 1≤i≤k1≤i≤k ,都有 ai<biai​<bi​ 。

由于这个问题太简单了,所以,这个问题的作者准备改进题目,让它变得更有挑战性。现在,基于前面的问题,我们再给定一个正整数 mm 。对于 mm 个数组对 (c[i],b)(c[i],b),即 (c[1],b),(c[2],b),...,(c[m],b)(c[1],b),(c[2],b),...,(c[m],b) ,根据前面的问题要求,分别计算出它们的答案,最后,你要给出所有答案的总和。其中,1≤i≤m1≤i≤m 。注意,数组 c[i]c[i] 是从 aa 数组转化而来的。下面是关于数组 c[i]c[i] 的定义:

  • c[i]1=i,
  • c[i]j=aj ,其中 2≤j≤n。

输入

第一行包含一个整数 t ,表示测试样例的数量。

对于每个测试样例,第一行包含两个整数 n,m,表示数组 a,b的大小,以及元素 a1值的上限。

第二行包含 n−1 个整数 a2,...,an 。

第三行包含 n 个整数 b1,b2,...,bn 。

输出

对于每个测试样例,输出所有数组对 (ci,b)的最小操作数的总和。

样例输入

4 2 1 1 3 2 4 1 5 1 5 3 8 3 3 8 1 4 3 3 2 2 1 1 1 1 1 1 3 3 3 3 9 1 9 2 8 3 7 4 6 5 1 2 3 2 1 4 5 6 5

样例输出

0 1 4 4

提示

数据范围

对于 100%100% 的数据,保证:

1≤t≤10^4, 2≤n≤10^5, m=1, 1≤ai≤109, 1≤bi≤109。

保证所有的测试样例 n 的总和不超过 10^5 。


题目解析

这道题目要求我们找到每个数组对 (c[i],b)的最小操作次数,并最终输出这些操作次数的总和。题目通过对数组 ab 进行特定操作,要求确保 **'a[i]<b[i]'**在每一轮操作后保持成立。

问题解析

  • 给定两个数组 ab,需要从两个数组中删除元素,并保证在**每轮操作后 a[i] < b[i]**对每个 i 成立。
  • 操作次数就是每次删除的次数,最后我们要计算每个测试样例的总操作次数
  • 特别地,数组 c[i] 是从 a 数组转化而来的,其中 c[i][1] = i ,而 c[i][j] = a[j](对于 2≤j≤n

解决思路

  • 对于每个数组对 (c[i],b)(c[i], b)(c[i],b),我们可以首先将 ab 排序,这样可以方便找到满足条件 'a[i]<b[i]'`a[i] < b[i]`'a[i]<b[i]' 的最优方案。
  • 数组 a 可以重新排序,找到最小的操作次数(最少删除元素的次数)使得对每个 ia[i] < b[i] 成立。
  • 对于数组对的数量 m,我们需要对每一个 c[i] 数组分别计算操作数,然后将结果相加。

代码实现

java 复制代码
import java.util.Arrays;
import java.util.Scanner;

public class MinOperations {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();  // 测试样例的数量

        while (t-- > 0) {
            int n = scanner.nextInt();  // 数组大小 n
            int m = scanner.nextInt();  // m 个数组对

            int[] a = new int[n - 1];   // 读取 a 数组(去掉 a1)
            for (int i = 0; i < n - 1; i++) {
                a[i] = scanner.nextInt();
            }

            int[] b = new int[n];   // 读取 b 数组
            for (int i = 0; i < n; i++) {
                b[i] = scanner.nextInt();
            }

            int totalOperations = 0;   // 操作次数的总和

            for (int i = 1; i <= m; i++) {
                // 创建 c[i] 数组,第一个元素是 i,接下来的元素是 a 数组
                int[] c = new int[n];
                c[0] = i;  // 第一个元素为 i
                for (int j = 1; j < n; j++) {
                    c[j] = a[j - 1];
                }

                // 对 c 和 b 数组进行排序
                Arrays.sort(c);
                Arrays.sort(b);

                // 计算最小的操作次数:使得 c[i] < b[i] 对于所有 i 成立
                int operations = 0;
                int bIndex = 0;
                for (int cIndex = 0; cIndex < n; cIndex++) {
                    while (bIndex < n && c[cIndex] >= b[bIndex]) {
                        bIndex++;  // 如果 b 数组中的数不满足条件,跳过
                    }
                    if (bIndex < n) {
                        bIndex++;  // 匹配一个,继续下一个
                    } else {
                        operations++;  // 如果不匹配,增加操作数
                    }
                }

                totalOperations += operations;  // 累计操作次数
            }

            System.out.println(totalOperations);  // 输出所有数组对的操作次数总和
        }

        scanner.close();
    }
}
相关推荐
CoderYanger3 分钟前
C.滑动窗口-求子数组个数-越短越合法——3258. 统计满足 K 约束的子字符串数量 I
java·开发语言·算法·leetcode·1024程序员节
2301_807997389 分钟前
代码随想录-day56
算法
AI科技星17 分钟前
时空运动的几何约束:张祥前统一场论中圆柱螺旋运动光速不变性的严格数学证明与物理诠释
服务器·数据结构·人工智能·python·科技·算法·生活
杰克尼23 分钟前
蓝桥云课-13. 定时任务
java·开发语言·算法
一个不知名程序员www36 分钟前
算法学习入门---list与算法竞赛中的链表题(C++)
c++·算法
CoderYanger38 分钟前
动态规划算法-路径问题:9.最小路径和
开发语言·算法·leetcode·动态规划·1024程序员节
老欧学视觉38 分钟前
0012机器学习KNN算法
人工智能·算法·机器学习
月明长歌1 小时前
【码道初阶】一道经典的简单题:Boyer-Moore 多数投票算法|多数元素问题(LeetCode 169)
算法·leetcode·职场和发展
CoderYanger1 小时前
动态规划算法-路径问题:7.礼物的最大价值
开发语言·算法·leetcode·动态规划·1024程序员节
蕓晨1 小时前
钱币找零问题-贪心算法解析
c++·算法·贪心算法