题目描述:
数组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为
B[0] B[1] B[2]
A[0] 2 4 6
A[1] 3 6 9
A[2] 4 8 12
共9个数。
输入
第1行:2个数N和K,中间用空格分隔。N为数组的长度,K对应第K大的数。(2 <= N <= 50000,1 <= K <= 10^9)
第2 - N + 1行:每行2个数,分别是A[i]和B[i]。(1 <= A[i],B[i] <= 10^9)
输出
输出第K大的数。
输入样例
3 2
1 2
2 3
3 4
输出样例
9
解题思路:
核心代码:
完整代码:
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[50010],b[50010],tot,ans;
int Conset(long long x)
{
tot = 0;
int j = n - 1;// j从最后位置开始
for(int i = 0;i < n;i++)
{
while(a[i] * b[j] > x) j--;//由于a[]从小到大,所以 j肯定是从上往下走
tot += n - j - 1; //统计出比 x大的数的个数
}
return tot;
}
int main()
{
scanf("%lld%lld",&n,&k);
for(int i = 0;i < n;i++)
scanf("%lld%lld",&a[i],&b[i]);
sort(a ,a + n);//从小到大排序
sort(b ,b + n);
long long L = a[0] * b[0],R = a[n - 1] * b[n - 1];
while(L < R - 1)
{
long long mid = (L + R) >> 1;
if(Conset(mid) < k)
{
ans = mid;//有可能是答案
R = mid;//范围缩小一点,才能使比 k大的数更多
}
else
L = mid;
}
cout << ans << endl;
return 0;
}