【发布时间】:2016-02-01 14:03:23
【问题描述】:
所以,我正在尝试解决这个问题:http://codeforces.com/contest/448/problem/D
Bizon the Champion 不仅迷人,而且非常聪明。
当我们中的一些人在学习乘法表时,Bizon the Champion 以他自己的方式玩得很开心。 Bizon the Champion画了一个n × m的乘法表,其中第i行j列的交点上的元素等于i·j(表的行和列从1开始编号)。然后他被问到:表中第k大的数字是多少? Bizon the Champion 总是正确而迅速地回答。你能重复他的成功吗?
考虑给定的乘法表。如果你把表中的所有n·m个数按非递减的顺序写出来,那么你写出的第k个数称为第k个最大数。
输入 单行包含整数 n、m 和 k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m)。
输出 打印 n × m 乘法表中第 k 个最大的数。
我所做的是,我应用从 1 到 n*m 的二进制搜索来寻找恰好小于它的 k 元素的数字。为此,我编写了以下代码:
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
ll n,m;
int f (int val);
int min (int a, int b);
int main (void)
{
int k;
cin>>n>>m>>k;
int ind = k;
ll low = 1LL;
ll high = n*m;
int ans;
while (low <= high)
{
ll mid = low + (high-low)/2;
if (f(mid) == k)
ans = mid;
else if (f(mid) < k)
low = mid+1;
else
high = mid-1;
}
cout<<ans<<"\n";
return 0;
}
int f (int val)
{
int ret = 0;
for ( int i = 1; i <= n; i++ )
{
ret = ret + min(val/i,m);
}
return ret;
}
int min (int a, int b)
{
if (a < b)
return a;
else
return b;
}
但是,我不知道为什么,但这对测试用例给出了错误的答案:
input
2 2 2
output
2
我的输出是 0
我正在学习二分搜索,但我不知道这个实现哪里出了问题。任何帮助将不胜感激。
【问题讨论】:
-
这不是关于搜索,第 k 个最大的数是从末尾开始写入的第 k 个元素。您可以使用模运算和标准运算直接计算它。
-
如果你能准确找到答案,你需要一个
break,否则这种情况将是一个无限循环。但根据您报告的症状,这不是唯一的错误。 -
@Dese,但是你怎么写这样的元素呢?复杂度将大于 O(n^2) 并且不支持给定的限制。
-
@JSF,即使破解了,好像也不管用。
-
@hans 第一个最大的元素是 n*m,第二个最大的元素是 n*(m-1),第三个是 n*(m-3)....行首:n,则根据定义为 (n-1)*m。 (参见 2 X 3 乘法表的例子,如果你真的在谈论最大的元素,那么第 4 个是 2: 6 4 3 2 但它们的定义是关于书写顺序的,所以答案是 3)。我说的是找到一个公式,使得结果 = f(n,m,k)。
标签: c++ algorithm binary-search