題目
給定乙個由 nn 個整數組成的陣列 aa,其中nn 為奇數。
你可以對其進行以下操作:
你最多可以進行 kk 次操作,並希望該陣列的中位數能夠盡可能大。
奇數長度的陣列的中位數是陣列以非降序排序後的中間元素。
例如,陣列 [1,5,2,3,5][1,5,2,3,5] 的中位數為 33。
輸入格式
第一行包含兩個整數 nn 和 kk。
第二行包含 nn 個整數 a1,a2,…,ana1,a2,…,an。
輸出格式。
輸出乙個整數,表示通過操作可能得到的最大中位數。
資料範圍
對於 30%30% 的資料,1≤n≤51≤n≤5。
對於 100%100% 的資料,1≤n≤2×1051≤n≤2×105,1≤k≤1091≤k≤109,1≤ai≤1091≤ai≤109。
輸入樣例1:
3 2
1 3 5
輸出樣例1:5
輸入樣例2:5 5
1 2 1 1 1
輸出樣例2:3
輸入樣例3:7 7
4 1 2 4 3 4 4
輸出樣例3:5
(二分) o(n(logn+lo**))o(n(logn+logv))
二分答案,設當前二分的值為 x,考慮如何判斷中位數是否可以超過 x。
首先將陣列 a 排序以方便判定。
記中位數的位置 p=(n+1)/2。
那麼對於 a 中所有位置小於 p 的數,我們一定不需要修改這個數,因為如果我們將其中某個數加上了 d,那麼把 d 加到乙個位置 ≥p 的數上一定更優。
所以此時我們要做的事,就是判斷是否可以讓所有位置 ≥p 的數都 ≥x。
我們可以讓所有位置 ≥p 的數都 ≥x,求代價的最小值 v,若 v≤k,則答案可以超過 x。
列舉所有位置 ≥p 的數 aj,如果這個數比 x 小,則將這個數修改成 x,將代價加入 v 即可。
時間複雜度
排序複雜度是 o(nlogn)o(nlogn)。
二分複雜度是 o(nlo**)o(nlogv),其中 v 表示答案的值域。
故總複雜度為 o(n(logn+lo**))o(n(logn+logv))。
#include #include #include #include using namespace std;
const int n = 200005;
int n, k;
int a[n];
bool check(int mid)
int main()
cout
}
最大中位數 二分
給定乙個由 n n n 個整數組成的陣列 a a a,其中 n n n 為奇數。你可以對其進行以下操作 選擇陣列中的乙個元素 例如 a i a i 將其增加 1 1ai 1 你最多可以進行 k k 次操作,並希望該陣列的中位數能夠盡可能大。奇數長度的陣列的中位數是陣列以非降序排序後的中間元素。例如,...
中位數的中位數
參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...
BFPRT(中位數的中位數)演算法
又稱為 中位數的中位數演算法 該演算法由 blum floyd pratt rivest tarjan 在1973年提出,最壞時間複雜度為o n 最差的空間複雜度為o logn 演算法步驟 1 將 n 個元素劃分為 n 5 個組,每組 5 個元素,若有剩餘,捨去 2 使用排序方法找到 n 5 個組中...