2018年蓝桥杯B组c/c++ 第六题详解

标题:递增三元组

给定三个整数数组
A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:

  1. 1 <= i, j, k <= N
  2. Ai < Bj < Ck

【输入格式】
第一行包含一个整数N。
第二行包含N个整数A1, A2, … AN。
第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。

对于30%的数据,1 <= N <= 100
对于60%的数据,1 <= N <= 1000
对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000

【输出格式】
一个整数表示答案

【样例输入】
3
1 1 1
2 2 2
3 3 3

【样例输出】
27

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include
不能通过工程设置而省略常用头文件。

提交程序时,注意选择所期望的语言类型和编译器类型。

/*

整体逻辑:

将三个数组都进行排序,然后枚举b中的数值,
    在a中找到所有比b[i]小的元素,在c中找到所有比b[i]大的元素
        两者相乘即可,将每一轮的乘积进行相加,就是结果值
        在查找元素的时候,使用了 algorithm 里面的内置函数
		lower_bound():查找大于或者等于b[i]的第一个位置
		upper_bound():查找大于b[i]的第一个位置
    注意:返回的都是十六进制地址,需要进行处理之后才可以使用;
	 一般的使用方法是:lower_bound(a, a+n, b[i]) - a;
则会返回等于或者大于b[i]的第一个元素位置

*/

#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAX 100005
using namespace std;
int a[MAX], b[MAX], c[MAX];
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
    }
    for(int i = 0; i < n; i++){
        scanf("%d", &b[i]);
    }
    for(int i = 0; i < n; i++){
        scanf("%d", &c[i]);
    }
    sort(a, a+n);
    sort(b, b+n);
    sort(c, c+n);
    int sum = 0;
    for(int i = 0; i < n; i++){
        int x = (lower_bound(a, a+n, b[i]) - a);        //查找大于或者等于b[i]的第一个位置
        int y = n - (upper_bound(c, c+n, b[i]) - c);    //查找大于b[i]的第一个位置
        sum += x*y;
    }
    //cout << upper_bound(c, c+n, b[2])-c << endl;
    printf("%d\n", sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39459624/article/details/83828758