问题描述:
在一块长为n,宽为m的场地上,有n✖️m个1✖️1的单元格。每个单元格上的数字就是按照从1到n和1到m中的数的乘积。具体如下
n = 3, m = 3
1 2 3
2 4 6
3 6 9
给出一个查询的值k,求出按照这个方式列举的的数中第k大的值v。
例如上面的例子里,
从大到小为(9, 6, 6, 4, 3, 3, 2, 2, 1)
k = 1, v = 9
k = 2, v = 6
k = 3, v = 6
...
k = 8, v = 2
k = 9, v = 1
输入描述:
只有一行是3个数n, m, k 表示场地的宽高和需要查询的k。使用空格隔开。
输出描述:
给出第k大的数的值。
输入例子:
3 3 4
输出例子:
4
代码实现:
import java.util.*;
public class Main {
public static void problem5_2020() {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int k = scanner.nextInt();
int left = 1;
int right = m * n;
k = m * n - k + 1;
while (left < right) {
// 注意int类型溢出问题!
int mid = (int)(((long)left + right) / 2);
// 求小于等于 mid 的数量
int row = mid / m;
int count = row * m;
for (int i = row + 1; i <= n; i++) {
count += mid / i;
}
if (count < k) {
left = mid + 1;
} else {
right = mid;
}
}
System.out.println(left);
}
public static void main(String[] args) {
problem5_2020();
}
}