cuit校赛--sort 第K个数

来源:互联网 发布:电商发展数据统计 编辑:程序博客网 时间:2024/06/06 01:16

传送门

sort

发布时间: 2017年5月28日 21:29   最后更新: 2017年5月28日 21:33   时间限制: 1000ms   内存限制: 128M

给两个序列A=(a1,a2,a3,…an)和B=(b1,b2,b3,…bm),A中有n个数,B中有m个数,把A中的每个数分别和B中的每个数乘起来得到n*m个数从小到大排序,求其中的第k个数。

第一行包含三个整数:n(1<=n<=10000),m(1<=m<=10000),k(1<=k<=m*n)。
第二行有n个整数,表示序列A。
第三行有m个整数,表示序列B。
A和B中所有数都在[0,10000]。
每个测试样例后都有一个空格。

对于每组测试数据,每行输出答案。

 复制
1 3 313 2 1
3
 复制
3 3 71 2 33 2 1
6

先排序,最大的肯定是a[m-1]*b[n-1],二分就是在l=0,r=a[m-1]*b[n-1] 里找

按照顺序来找。

a 0 1 2 3 4 5 `````

b 0 1 2 3 4 5 `````

如果是没有重复数字的情况下。

那么第K大的数一定是 m*x+y

比如K是 11 a有6个数

那么 b的第一个数乘以a的6个数 已经到了第6位。

b的第二个数乘a的5个数就到了11位。

所以二分找第k大的数


#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int maxn = 10005;#define ll long longint a[maxn];int b[maxn];int m, n, k;int getsum(int x){    int l = 0, r = n - 1;    while (l <= r)    {        int mid = (l + r) >> 1;        if (b[mid] <= x)            l = mid + 1;        else            r = mid - 1;    }    return l;}bool check(int x){    ll ans = 0;    for (int i = 0; i < m; i++)    {            if (!a[i])// 如果a[i] 是0的话 那么这一排m必取            {                ans += n;                continue;            }            int cnt = x / a[i];//a[i]* cnt=x; 求最大的cnt 其他比            //cnt小的 都要加起来            ans += getsum(cnt);//在b里找 比cnt小的    }     return ans >= k;}int main(){    scanf("%d %d %d",&m,&n,&k);    for(int i=0;i<m;i++) scanf("%d",&a[i]);    for(int i=0;i<n;i++) scanf("%d",&b[i]);    sort(a,a+m);    sort(b,b+n);    int l = 0;    int r = a[m-1]*b[n-1];    while(l<=r)    {        int mid = (l+r)>>1;        if(check(mid)) r = mid-1;        else l = mid+1;    }    cout << l << endl;}




原创粉丝点击