题目
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
LL C(int a, int b) //计算C(a,b)
{
LL res = 1;
for(int i = a, j = 1; j <= b; i --, j ++)
{
res = res * i / j;
if(res > n)
return res; // 大于n已无意义,且防止爆LL
}
return res;
}
bool check(int k)
{
// 二分该斜行,找到大于等于该值的第一个数
// 左边界2k,右边界为max(l, n)取二者最大,避免右边界小于左边界
int l = 2 * k, r = max(n,l);
while(l < r)
{
int mid = l + r >> 1;
if(C(mid, k) >= n) r = mid;
else l = mid + 1;
}
if(C(r, k) != n)
return false;
cout << 1ll*(r + 1) * r / 2 + k + 1 << endl;
return true;
}
int main()
{
cin >> n;
// 从第16斜行枚举
for(int i = 16; ; i--)
if(check(i))
break;
return 0;
}
时间复杂度:
O
(
16
l
o
g
n
)
O(16logn)
O(16logn)
本文介绍了一个计算组合C(a, b)并利用二分查找优化的C++程序,用于解决特定数学问题。代码中定义了计算组合的函数C(int a, int b),并实现了检查某斜行是否存在等于n的组合值的功能。通过从第16斜行开始枚举,最终找到满足条件的斜行并输出相关信息。时间复杂度为O(16logn)。

977

被折叠的 条评论
为什么被折叠?



