Week4 TT的神秘禮物 二分法求中位數

2021-10-04 03:51:22 字數 2612 閱讀 7665

題目內容

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 非常想得到那只可愛的貓咪,你能幫幫他嗎?

輸入格式

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

輸出格式

輸出新陣列 ans 的中位數。

輸入示例

4

1 3 2 4

31 10 2

輸出示例

1

8

解題思路顯然如果我是tt的話我就會放棄這只貓。

哎,中位數嘛,如果能把n的範圍縮小一點那這道題將可以直接暴力演算法絕殺,可惜換不得。

所以怎麼二分呢?

對於一串數字,我們在已知這串數字的數量n的情況下,可以很容易地求得其中位數所在的位置為(n+1)>>1。

那麼如果我們反著來看呢?

很明顯我們即便不把ans陣列直接算出來,也可以提前預判到其中位數所在的位置應該是((n * (n - 1)) / 2 + 1) / 2,此處n為cat陣列的大小。

因此我們就可以繼續分析:

已知了中位數的位置,我們只需要對ans進行二分:

那麼對於某乙個ans中的數p,

只需要求出小於等於它的數的個數就行了,這個個數如果等於中位數應該擁有的個數,那就說明p是中位數。

當然了,如果p比中位數少或者多,所以二分就行了。

但是既然用到了二分,那麼我們就需要必要條件:被二分的陣列應該是單調的。

看看題目:ans = abs(cat[i] - cat[j])

我們如何才能把絕對值化掉呢?

顯然只需要保證cat[i]大於cat[j]就可以了。

我們可以提前對cat進行排列,然後保證i大於j就行了。

因此此時的式子變成了:p>=cat[i]-cat[j],其中i>j。

把cat[j]挪到式子左邊:p+cat[j]>=cat[i]。

對於某個二分出來的p,我們只需要固定j,然後二分i就行了,這樣就可以求出所有滿足此式子的i和j的對數,即ans陣列裡小於等於p的數的個數。

複雜度為o(logk+nlogn),可以接受。

於是有**:

#include

#include

#include

#include

using

namespace std;

vector<

int>cat;

int n;

bool

cmp(

const

int& a,

const

int& b)

intfun

(int

&mid,

const

int&rank)

else r = mid2 -1;

}if(ans !=-1

) currank +

= ans - i;}if

(currank < rank)

return1;

//小於

if(currank >= rank)

return2;

//大於等於

}int

main()

sort

(cat.

begin()

, cat.

end(

), cmp)

;int rank =

((n *

(n -1)

)/2+

1)/2

;//中位數的名次

int l =

0, r = cat.

back()

- cat.

front()

,ans=-1

;while

(l <= r)

else

if(opnum ==1)

}if(ans !=-1

) cout << ans << endl;

}}

如果使用iostream,顯然不要忘記使用

ios::

sync_with_stdio

(false);

cin.

tie(0)

;

血的教訓

C 二分法查詢,遞迴二分法

用二分法來求需要查詢的值.includeusing namespace std 查詢key元素是否存在 int findkey const int buf 100 const int ilen,const int key else right left mid 1 查詢失敗 return 1 查詢k...

python二分法查詢 Python 二分法查詢

二分法查詢主要的作用就是查詢元素 lst 1,3,5,7,12,36,68,79 資料集 百萬級資料 num int input 請輸入你要查詢的元素資訊 for el in lst if num el print 存在 break else print 不存在 len lst 0 1 2 3 4 ...

TT的神秘禮物 Week4作業C題

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