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:這題的主要方法是二分法。根據新陣列的生成ans = abs(cat[i] - cat[j]),1 <= i < j <= n可以將cat陣列公升序排列,這樣就可以去除絕對值。然後對0 ~ (cat[n] - cat[1])進行二分查詢,根據二分後的結果的名次判斷是否為中位數。多組輸入,每次輸入乙個 n,表示有 n 個數,之後輸入乙個長度為 n 的序列 cat, cat[i] <= 1e9 , 3 <= n <= 1e5
output:輸出新陣列 ans 的中位數
example:
sample input:
41 3 2 4
31 10 2
sample output:18
我們可以將這個題的解題過程分為兩大部分:
一:在0 ~ (cat[n] - cat[1])中二分查詢中位數。我們在二分的時候判斷mid的名次和中位數的名次之間的關係,由於在ans陣列中會存在重複值,在名次計算的演算法中數的名次可能會大於等於中位數的名次。
二:求mid在ans陣列中的名次。這裡我們只需要找比mid小的數的個數,即滿足cat[j]-cat[i]<=mid的i,j數對的數量,這裡我們移項可以得到cat[j]<=mid + cat[i],這樣我們就可以通過列舉i來求所有滿足條件的下標j。這裡因為cat已經有序,這樣我們就可以使用二分法找到最大的大於等於*mid + cat[i]*的j的值。mid的名次就是每個最大的j值減去i的累加和。
#include
#include
#include
using
namespace std;
#define _rep(i,a,b) for( int i=(a); i<=(b); i++)
const
int n =
100010
;int n , cat[n]
;int
rank_p
(int p)
//計算p的名次
else r = mid -1;
}if(ans !=-1
) rank +
= ans -i;
}return rank;
}int
check()
//查詢中位數
else l = mid +1;
}return ans;
}int
main()
}
1.如果遇到比較複雜的題目,我們可以將它分成各個小的步驟處理,這樣可以更好地捋清思路,防止心態**…
2.這裡遇到了乙個之前沒有遇到的問題,就是*『+』的優先順序大於『>>』*,需要注意新增括號。
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,...
程式設計思維 week4 作業C TT 的神秘禮物
tt 是一位重度愛貓人士,每日沉溺於 b 站上的貓咪頻道。有一天,tt 的好友 zjm 決定交給 tt 乙個難題,如果 tt 能夠解決這個難題,zjm 就會買乙隻可愛貓咪送給 tt。任務內容是,給定乙個 n 個數的陣列 cat i 並用這個陣列生成乙個新陣列 ans i 新陣列定義為對於任意的 i,...