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大的数。
 
例如:A:1 2 3,B:2 3 4。A与B组合成的C包括2 3 4 4 6 8 6 9 12共9个数。
Input
第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)
Output
输出第K大的数。
Input示例
3 2
1 2
2 3
3 4
Output示例
9

二分套二分
第一个二分第k大的数的值
然后枚举a数组 在b数组中二分查找大于第一个二分值的数

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 
 5 typedef long long LL;
 6 const int MAXN=50010;
 7 
 8 int n,k;
 9 
10 LL a[MAXN],b[MAXN];
11 
12 inline void read(LL&x) {
13     int f=1;register char c=getchar();
14     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
15     for(;isdigit(c);x=x*10+c-48,c=getchar());
16     x=x*f;
17 }
18 
19 inline bool check(LL x) {
20     LL ans=0;
21     for(int i=1;i<=n;++i) {
22         if(a[i]*b[n]<x) continue;
23         LL l=0,r=n+1;
24         while(l+1<r) {
25             LL mid=(l+r)>>1;
26             if((LL)a[i]*b[mid]>=x) r=mid;
27             else l=mid;
28         }
29         ans+=n-r+1;
30     }
31     return ans>=k;
32 }
33  
34 int hh() {
35     scanf("%d%d",&n,&k);
36     for(int i=1;i<=n;++i) read(a[i]),read(b[i]);
37     std::sort(a+1,a+1+n);
38     std::sort(b+1,b+1+n);
39     LL l=0,r=(LL)a[n]*b[n]+1;
40     while(l+1<r) {
41         LL mid=(l+r)>>1;
42         if(check(mid)) l=mid;
43         else r=mid;
44     }
45     printf("%lld\n",l);
46     return 0;
47 }
48 
49 int sb=hh();
50 int main(int argc,char**argv) {;}
代码

 

 
posted @ 2017-09-20 15:32  拿叉插猹哈  阅读(247)  评论(0编辑  收藏  举报