ZCMU-1540-第K大个数
2017-01-05 16:36
288 查看
1540: 第k大数
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 420 Solved: 47
[Submit][Status][Web
Board]
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
33 2 3
1 2 3
1 2
2 2 1
1 1
1 1
2 2 4
1 1
1 1
Sample Output
31
1
【解析】
这道题其实又是一道考验你算法的题。如果直接模拟肯定不行的要么超时要么空间复杂度太高。这个时候我们就要思考了。我们应该怎么办?还是二分查找...不过这个二分查已经不一样了。
#include <iostream> #include <cstdio> #include <algorithm> typedef long long LL; using namespace std; int t,n,m,k; LL a[100005],b[100005]; LL judge(LL mid) { LL cnt = 0; int j = 0; for(int i = n-1;i>=0;i--) { while(j<m) { if(a[i]*b[j]>=mid) { cnt+=m-j;//记录比大于等于mid的数量 break; } else { j++; } } } return cnt; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(int i = 0;i<n;i++) { scanf("%d",&a[i]); } for(int i = 0;i<m;i++) { scanf("%d",&b[i]); } sort(a,a+n); sort(b,b+m); LL right,mid,left,p; right= a[0]*b[0]; left= a[n-1]*b[m-1];//mid取它们中间的值 while(right<=left) { mid = (right+left)/2; LL cnt = judge(mid); if(cnt>=k) { p=mid; right=mid+1;//往后搜索比mid大的比K多了 } else { left=mid-1;//比mid大的比K少了 } } printf("%lld\n",p); } return 0; }
相关文章推荐
- zcmu 1540: 第k大数
- ZCMU 1540 第k大数 (二分)
- zcmu1540 第k大数
- ZCMU—1540
- 1540 第k大数
- ZCMU-1305-第K完美序列
- 1540: 第k大数 两个数组元素相乘后的第k大( 二分答案 + 输入输出优化 )
- 编程练习——求无序数组第k小的数
- 快速选择——寻找第k小的数
- tyvj P1001:第K极值
- SBT的应用——求区间第k值——poj2761
- 找包含N个元素的数组里第K大的元素(引申:快速排序、找中位数、找前K大的元素)的时间复杂度
- 数组中求第K大数
- HDU 2852 树状数组解决第K小数 附线段树解法
- hdu 3727 Jewel 划分数+树状数组 求区间和当前段的第k大数
- 快排求第k大数
- HDU 1540 Tunnel Warfare
- 求无序数组第K大的数值,及其所在的位置
- 在两个已经排好序的数组里找出第K小的数
- POJ-2761-树状数组+第k小数+离散化