1. 程式人生 > >2018年藍橋杯B組c/c++ 第六題詳解

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;
}