合并两个数组,新数组第k小的元素---二分--九度OJ1534

来源:互联网 发布:cc域名免费注册 编辑:程序博客网 时间:2024/06/05 14:07

题目1534:数组中第K小的数字

时间限制:2 秒

内存限制:128 兆

特殊判题:

提交:2005

解决:436

题目描述:

给定两个整型数组A和B。我们将A和B中的元素两两相加可以得到数组C。
譬如A为[1,2],B为[3,4].那么由A和B中的元素两两相加得到的数组C为[4,5,5,6]。
现在给你数组A和B,求由A和B两两相加得到的数组C中,第K小的数字。

输入:

输入可能包含多个测试案例。
对于每个测试案例,输入的第一行为三个整数m,n, k(1<=m,n<=100000, 1<= k <= n *m):n,m代表将要输入数组A和B的长度。
紧接着两行, 分别有m和n个数, 代表数组A和B中的元素。数组元素范围为[0,1e9]。

输出:

对应每个测试案例,
输出由A和B中元素两两相加得到的数组c中第K小的数字。

样例输入:
2 2 31 23 43 3 41 2 73 4 5
样例输出:
56
来源:
Google面试题
#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <algorithm>using namespace std;const int N = 1e5 + 7;typedef long long LL;LL a[N], b[N];LL cal(LL a[], LL b[], int n, int m, LL mid) { //返回小于等于mid的两数和的个数LL cnt = 0; int j = m - 1;for (int i = 0; i < n; ++i) {while (j >= 0 && a[i] + b[j] > mid)--j;cnt += 1 + j;}return cnt;}LL findK(LL a[], LL b[], int n, int m, LL k) {sort(a, a + n);sort(b, b + n);LL l = a[0] + b[0], r = a[n - 1] + b[m - 1];while (l <= r) {LL mid = l + r >> 1;if (k <= cal(a, b, n, m, mid)) r = mid - 1;else l = mid + 1;}return l;}int main(){int n, m; LL k;while (~scanf("%d%d%lld", &n, &m, &k)) {for (int i = 0; i < n; ++i)scanf("%lld", a + i);for (int i = 0; i < m; ++i)scanf("%lld", b + i);printf("%lld\n", findK(a, b, n, m, k));}return 0;}

数据范围较大,小心int溢出


阅读全文
0 0
原创粉丝点击