zcmu1540 第k大数
来源:互联网 发布:掏粪男孩 知乎 编辑:程序博客网 时间:2024/05/18 02:43
这道题来自首届全国中医药院校大学生程序设计大赛。类似于POJ3579都是寻找第K大数
Description
有两个序列a,b,它们的长度分别为n和m,那么将两个序列中的元素对应相乘后得到的n*m个元素从大到小排列后的第k个元素是什么?
Input
输入的第一行为一个正整数T (T<=10),代表一共有T组测试数据。
每组测试数据的第一行有三个正整数n,m和k(1<=n, m<=100000,1<=k<=n*m),分别代表a序列的长度,b序列的长度,以及所求元素的下标。第二行为n个正整数代表序列a。第三行为m个正整数代表序列b。序列中所有元素的大小满足[1,100000]。
Output
对于每组测试数据,输出一行包含一个整数代表第k大的元素是多少。
Sample Input
3
3 2 3
1 2 3
1 2
2 2 1
1 1
1 1
2 2 4
1 1
1 1
3 2 3
1 2 3
1 2
2 2 1
1 1
1 1
2 2 4
1 1
1 1
Sample Output
3
1
1
思路是假设一个值mid,然后判断mid的位置,再二分搜索用逐步缩小区间查找到第k大数1
1
#include <iostream>#include <cstdio>#include <algorithm>typedeflonglongLL;using namespace std; int T,n,m,k;LL a[100005],b[100005]; LL judge(LL mid){ LL cnt = 0; intj = 0; for(inti = n-1;i>=0;i--) { while(j<m) { if(a[i]*b[j]>=mid) { cnt += m-j; //这个式子减少了很多不必要的运算 break; } else { j++; } } } returncnt;} int main(){ scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); for(inti = 0;i<n;i++) { scanf("%d",&a[i]); } for(inti = 0;i<m;i++) { scanf("%d",&b[i]); } sort(a,a+n); sort(b,b+m); LL r,mid,l,x; r = a[0]*b[0]; l = a[n-1]*b[m-1]; while(r<=l) { mid = (r+l)/2; LL cnt = judge(mid); //用judge查找大于mid的数的个数,用cnt记录,然后二分搜索 if(cnt>=k) { x = mid; r = mid+1; } else { l = mid-1; } } printf("%lld\n",x); } return0;}
1 0
- zcmu1540 第k大数
- 求第k大数
- 第K大数问题
- 寻找第k大数
- 区间第K大数
- 区间第K大数
- 求第k大数
- 第K大数问题
- 找到第K大数
- 找第K大数
- 找第K大数
- 求第k大数
- 求第k大数
- 1540 第k大数
- 第k大数 二分法
- //第二大数(第k大数)
- 第K大数的位置...
- 第(前)k大数问题
- 设计模式六大原则(5)-迪米特法则
- 正式入驻CSDN
- 偶遇两个好博客
- Android Graphics Pipeline: From Button to Framebuffer (Part 1)
- swift 快速奔跑的兔几 本节的内容是:绘画第二讲~
- zcmu1540 第k大数
- JAVA_SE基础——49.多态的应用
- 设计模式六大原则(6)-开闭原则
- JavaMail
- 流式计算的理论与技术
- Android Dialog点击按钮不关闭对话框
- HDU5510Bazinga(暴力剪枝)
- 大数据环境下的云计算与物联网
- flash乱码解决方案