陣列a和陣列b,裡面都有n個整數。
陣列c共有n^2個整數,分別是:
a[0] * b[0],a[0] * b[1] ...... a[0] * b[n-1]
a[1] * b[0],a[1] * b[1] ...... a[1] * b[n-1]
......
a[n - 1] * b[0],a[n - 1] * b[1] ...... a[n - 1] * b[n - 1]
是陣列a同陣列b的組合,求陣列c中第k大的數。
例如:a:1 2 3,b:2 3 4。
a與b組合成的c為
a[0] a[1] a[2]
b[0] 2 3 4
b[1] 4 6 8
b[2] 6 9 12
共9個數。
除錯日誌: 沒有弄清二分值在滿足條件的情況下是應該盡可能小還是盡可能大
首先對兩陣列進行排序
現在解決這乙個問題: 給定乙個數 \(k\) 求兩兩相乘 \(n^\) 個數中有多少個 \(<= k\)
類似 \(two points\) 解決
因為已經排序, 所以在確定一組解 \(a_ * b_ <= k\) 後, 隨著 \(i\) 的遞增, 若繼續滿足條件 \(j\) 必定遞減
這樣便可以在 \(o(n)\) 的時間內詢問一次
二分 \(k\) 即可得到答案
注意這裡是第 \(k\) 小, 需要轉換為第 \(k\) 大
然後複習二分
保險起見, 二分時無論寫法預設開區間
再保險起見, 二分時用變數 \(ans\) 記錄可行答案, 最後返回 \(ans\)
這時需要分清二分值在滿足條件的情況下是應該盡可能小還是盡可能大
其實不對你就換乙個就ok了, 不過我們不能糟蹋這門學科是吧
這題需要找的是序列中的值, 故二分的值盡可能小(來滿足存在於序列中)
#include#include#include#include#include#include#define ll long long
using namespace std;
ll rd()
while(c >= '0' && c <= '9')
return flag * out;
}const ll maxn = 100019;
ll num, k;
ll a[maxn], b[maxn];
bool check(ll k)
if(cnt < k)return 1;
return 0;
}ll search(ll l, ll r)
return ans;
}int main()
51Nod 1105 第K大的數
acm模版 這裡使用二分套二分查詢即可。一般的二分查詢是通過下標範圍查詢,而二分套二分是為了求兩個陣列組合乘積的問題,查詢第k大的值,這裡我們需要通過資料的範圍查詢,而不是下標的範圍,這裡需要兩次快排。需要強調的一點是資料範圍問題!一定要使用long long型,避免資料溢位!include inc...
51nod 1105 第K大的數
1105 第k大的數 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 陣列a和陣列b,裡面都有n個整數。陣列c共有n 2個整數,分別是a 0 b 0 a 0 b 1 a 1 b 0 a 1 b 1 a n 1 b n 1 陣列a同陣列b的組合 求陣列c中第k大的數...
51nod 1105第K大的數
1105 第k大的數 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 陣列a和陣列b,裡面都有n個整數。陣列c共有n 2個整數,分別是 a 0 b 0 a 0 b 1 a 0 b n 1 a 1 b 0 a 1 b 1 a 1 b n 1 a n 1 b 0 a ...