题目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 3 1 2 3 4 3 3 4 1 2 7 3 4 5
-
- 样例输出:
-
5 6
-
- 来源:
- 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溢出\
-