所以,我试图解决的问题:http://codeforces.com/contest/448/problem/D使用二进制搜索找到N * M个乘法表k大数字
BIZON冠军不只是迷人,他也很聪明。
当我们中的一些人正在学习乘法表时,Bizon冠军以他自己的方式玩得很开心。 Bizon Champion绘制了一个n×m的乘法表,其中第i行第j列的交点上的元素等于i·j(表格的行和列从1开始编号)。然后他问道:表中第几个数字是第几个数字? Bizon冠军总是立即正确回答。你能重复他的成功吗?
考虑给定的乘法表。如果以非递减顺序从表格中写出所有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个元素。您可以使用模和标准操作直接计算它。 – Dese
如果您完全找到答案,您需要一个“break”,否则这种情况将会是无限循环。但根据您报告的症状,这不是唯一的错误。 – JSF
@Dese,但你怎么写这样的元素?复杂度将大于O(n^2),并且不会支持给定的限制。 – hans