week4 C TT的神秘禮物

2021-10-04 03:53:26 字數 1868 閱讀 6821

tt 是一位重度愛貓人士,每日沉溺於 b 站上的貓咪頻道。

有一天,tt 的好友 zjm 決定交給 tt 乙個難題,如果 tt 能夠解決這個難題,zjm 就會買乙隻可愛貓咪送給 tt。

任務內容是,給定乙個 n 個數的陣列 cat[i],並用這個陣列生成乙個新陣列 ans[i]。新陣列定義為對於任意的 i, j 且 i

!= j,均有 ans = abs(cat[i] - cat[j]),1 <= i < j <=

n。試求出這個新陣列的中位數,中位數即為排序之後 (len+1)/2 位置對應的數字,』/』 為下取整。

tt 非常想得到那只可愛的貓咪,你能幫幫他嗎?

input

多組輸入,每次輸入乙個 n,表示有 n 個數,之後輸入乙個長度為 n 的序列 cat, cat[i] <= 1e9 , 3 <= n <= 1e5

output

輸出新陣列 ans 的中位數

sample input

413

2431

102

sample output
1

8

此題最容易想到的是暴力演算法, 即分別列舉x_i和x_j,得到新陣列ans後排序找到中位數,這樣複雜度是o(n^2),對於1e5的資料來說複雜度是不能接受的。

課上學長講到二分答案的方法,可以將複雜度降到n(logn)^2,感覺有一丟丟繞,下面詳細寫一寫。

1.二分答案:因為直接列舉求中位數複雜度太高,可以用驗證的方法,即給乙個數p,判斷其是否是中位數。中位數即名次排在乙個有序數列中間的數,因此我們可以求出p的名次,如果小於中位數的名次,則p比中位數小,如果p的名次比中位數大,則p大於中位數,如果p的名次與中位數相同,則p就是中位數。我們可以看到p的取值是單調的,因此可以二分p來尋找與中位數名次相同的p。二分時,先將cat陣列排序,可以去絕對值,p=x_j-x_i(i2.求p的名次:在單調數列b中,p=x_j-x_i,p的名次就為小於等於p的數的個數,即求滿足x_j-x_i<=p的二元組x_j、x_i的個數。變形一下:x_j<=x_i+p,因此,我們可以列舉每個x_i,找到滿足上述不等式的x_j的個數即p的名次。

3.再次二分:尋找x_j的過程又可以二分陣列cat得到,用滿足條件的mid來更新pos,最後得到區間[i,pos]的長度就是滿足條件的x_j的個數,也是p的名次。

4.求中位數的名次:數列b中有n(n-1)/2個數,中位數的名次為(n(n-1)/2+1)/2,位運算表示為((n*(n-1)>>1)+1)>>1。

#include

#include

#include

using namespace std;

const

int maxn=

1e5+5;

int cat[maxn]

;int n;

intfind

(int i,

int b)

else

r=mid-1;

}return pos-i;

//區間[i,pos]的長度就是滿足條件的x_j的個數

}int

find_p

(int index)

if(suml=mid+1;

else

r=mid-1;

}return l;

}int

main()

sort

(cat,cat+n)

;int mid_index=

((n*

(n-1

)>>1)

+1)>>1;

printf

("%d\n"

,find_p

(mid_index));

}return0;

}

Week4 C TT 的神秘禮物

給定乙個 n 個數的陣列 cat i 並用這個陣列生成乙個新陣列 ans i 新陣列定義為對於任意的 i,j 且 i j,均有 ans abs cat i cat j 1 i j n。試求出這個新陣列的中位數,中位數即為排序之後 len 1 2 位置對應的數字,為下取整。多組輸入,每次輸入乙個 n,...

week4 C TT的神秘禮物

tt 是一位重度愛貓人士,每日沉溺於 b 站上的貓咪頻道。有一天,tt 的好友 zjm 決定交給 tt 乙個難題,如果 tt 能夠解決這個難題,zjm 就會買乙隻可愛貓咪送給 tt。任務內容是,給定乙個 n 個數的陣列 cat i 並用這個陣列生成乙個新陣列 ans i 新陣列定義為對於任意的 i,...

week4 C TT 的神秘禮物

tt 是一位重度愛貓人士,每日沉溺於 b 站上的貓咪頻道。有一天,tt 的好友 zjm 決定交給 tt 乙個難題,如果 tt 能夠解決這個難題,zjm 就會買乙隻可愛貓咪送給 tt。任務內容是,給定乙個 n 個數的陣列 cat i 並用這個陣列生成乙個新陣列 ans i 新陣列定義為對於任意的 i,...