今日笔试遇到的题,想了好久没想出来,求个大佬解答下
题目:分别给出两个数n, m,再给出一个数k(1 <= n, m, k <= 1e6)
定义f(i, j) = i * j,其中 1 <= i <= n, 1 <= j <= m;
求所有f(i, j)结果中的第k大数
输入:三个整数n, m, k
输出一个整数:f(i, j)中第k大数
提示:相当于i从1 - n,j从1 - m分别相乘得到的数组
根据题意生成数据类似如下
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int n, m, k;
int main()
{
cin >> n >> m >> k;
int cnt = 0;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
a[cnt ++] = i * j;
sort(a, a + cnt);
for(int i = 0; i < cnt; i ++) cout << a[i] << " ";
return 0;
}
示例1:
输入: 3 3 4
输出: 4
示例1解释:所有f(i, j)排好序后为:1 2 2 3 3 4 6 6 9 其中第4大的数为4,因此输出4
示例2:
输入: 3 5 5
输出: 8
示例2解释:所有f(i, j)排好序后为:1 2 2 3 3 4 4 5 6 6 8 9 10 12 15 其中第5大数为8,因此输出8
k是1e6级别,是不是可以考虑直接从末尾暴力枚举呢,应该很难构造数据卡掉吧
总共的元素一共有m*n个,也就是1e12的数量,之间枚举的话时间复杂度爆了
我的意思是从最后开始枚举,它只要求第k大数,你从最后枚举,枚举到就退出,你并不需要枚举所有1e12,就比如最好的情况,你只需要枚举n~n-1000,m~m-1000,你就能找到第k大数,而这的时间复杂度是o(1e6)
怎么保证有序枚举
用set维护