原题链接
题目难度:中等
题目来源:第九届蓝桥杯省赛C++ B组,第九届蓝桥杯省赛Java B组
题目描述
给定三个整数数组
$A = [A_1, A_2, … A_N]$,
$B = [B_1, B_2, … B_N]$,
$C = [C_1, C_2, … C_N]$,
请你统计有多少个三元组 $(i, j, k)$ 满足:
- $1 \le i, j, k \le N$
- $A_i < B_j < C_k$
输入格式
第一行包含一个整数 $N$。
第二行包含 $N$ 个整数 $A_1, A_2, … A_N$。
第三行包含 $N$ 个整数 $B_1, B_2, … B_N$。
第四行包含 $N$ 个整数 $C_1, C_2, … C_N$。
输出格式
一个整数表示答案。
数据范围
$1 \le N \le 10^5$,
$0 \le A_i,B_i,C_i \le 10^5$
输入样例:
1 | 3 |
输出样例:
1 | 27 |
题目分析
这道题的意思很清楚,就是从A、B、C三个数组中选出三个数满足严格小于关系,问满足条件的三元组的个数
对于枚举类型的题目,最重要的就是枚举的顺序,要注意不重不漏,其次就是要对代码进行优化,利用题目性质,等式,进行优化
如果我们从暴力来做就是用三重循环,直接判断计数
这里考虑到这个不等式的关系,就是A小于B小于C,如果我们枚举的是A或者C,那么对于我们统计的B和C的数量,是无法简单的使用乘法原理直接相乘的,因为乘法原理是要求独立的,因此我们在这里是需要枚举B的,对于每一个B只需要在计算满足要求的A的个数,满足要求的C的个数,再相乘即可
那么这里的问题就是,如何快速计算出满足要求的A和C的个数,这其实是同一个问题了
我们将其抽象出来就是,在A中有多少个数小于B
我们能想到的第一个方法就是使用前缀和,第二个方法就是排序+二分,第三种方法就是使用双指针算法,我们暂时就先只使用前两个方法来做
我们首先开一个count数组,表示在A数组中,i的值出现的次数
然后我们再对这个count数组做前缀和,他的含义就是在A中从0到i的数字出现了多少次
示例代码
1 |
|