1. 程式人生 > >遞增三元組|2018年藍橋杯B組題解析第六題-fishers

遞增三元組|2018年藍橋杯B組題解析第六題-fishers

標題:遞增三元組

給定三個整數陣列
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
不能通過工程設定而省略常用標頭檔案。

提交程式時,注意選擇所期望的語言型別和編譯器型別。

思路:

遞增三元組,用三個陣列表示;先排序sort,找到b陣列中 第一個比a[i]大的數下標為j,找到c陣列中 第一個比a[i]大的數下標為k,計算公式:b中j後面的數都比a[i]大 k同理 組數=jk相乘

程式碼:

#include<iostream>
#include<algorithm>
using namespace std;

//4
//1 3 4 5 
//1 2 2 2
//2 3 3 4

int a[100010];
int b[100010];
int c[100010];
int n;
long long ans = 0;

int main(){
    //輸入資料 
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        cin>>b[i];
    }
    for(int i=1;i<=n;i++){
        cin>>c[i];
    }
    //排序 
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    sort(c+1,c+n+1);
    
    //定義兩個指標(下標) 
    int j = 1;
    int k = 1;
    for(int i=1;i<=n;i++){
        //找到b陣列中 第一個比a[i]大的數 
        while(j<=n && b[j]<a[i]){
            j++;
        }
//      cout<<"j="<<j;
        //找到c陣列中 第一個比a[i]大的數
        while(k<=n && c[k]<a[i]){
            k++;
        }
//      cout<<" k="<<k<<endl;
        if(j<=n && k<=n){
            ans += (n-j+1) * (n-k+1);//計算公式:b中j後面的數都比a[i]大 k同理 組數=jk相乘 
        }
    }
    cout<<ans<<endl;
}

解法二: