蓝桥杯-递增三元组

这道题很容易就想到暴力的三层循环,但是根据输入描述中的范围描述,可以知道如果在暴力三层循环下的最坏情况可以到达10^25,这是一定会超时的,因此我们必须来进行优化,它的优化方法是我在网上看到的,我今天就是来进行一个解释,各位网友也可以去看看别人写的,基本上都是这么做的。

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //在此输入您的代码...
        int N = sc.nextInt();

        int[] A = new int[N];
        int[] B = new int[N];
        int[] C = new int[N];

        for(int i = 0; i < N; i++){
          A[i] = sc.nextInt();
        }

        for(int i = 0; i < N; i++){
          B[i] = sc.nextInt();
        }

        for(int i = 0; i < N; i++){
          C[i] = sc.nextInt();
        }

        Arrays.sort(A);
        Arrays.sort(B);
        Arrays.sort(C);

        long sum = 0;
        int p = 0;
        int q = 0;
        for(int i = 0; i < N; i++){

          while(p < N && A[p] < B[i]){
            p++;
          }

          while(q < N && C[q] <= B[i]){
            q++;
          }

          sum += 1L * p * (N - q);
        }
        System.out.print(sum);
        sc.close();
    }
}

在这里是采取的将三个数组都进行排序,这是很容易想到的一个优化办法,但是仅仅只是靠这个优化是远远起不到效果的,重头戏是在while循环里。

通过采取将B数组作为中间枢纽,循环遍历每一个B数组中的数,分别从A数组中找到比B小的数,在C数组中,这里是通过侧面来寻找,因为sort排序后数组里的数都是从小到大排的,因此我们只能从侧面先找到比B数组中小或等于的数的个数来找到大于B数组中的数,最后在总和起来,有一个很重要的一点,就是为什么要把p和q写在while循环外,事实上,这也是一个优化点,因为所有的数组都是排好序了的,因此在遍历到B数组后面的数的时候,假如说是B[j],因为B[j]大于B[j-1],因此原来在A数组中小于B[j-1]的数现在仍然小于B[j],继续往后遍历,原来大于B[j-1]的数现在可能是小于B[j]中的数,直接在原有的基础上继续累加就可以了,同理对于C数组也是这也样,原来小于等于B[j-1]的数现在仍然是小于B[j]的,但是原来大于B[j-1]的数现在不一定大于B[j],因此也是要在原来的基础上来进行计算。

上面的每一个优化点都缺一不可,少了一个可能导致超时之类的错误。

以上便是我对此题代码的解释,希望能给大家提供到了帮助,如果有不对的地方,请大家指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈,啦啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值