题目
思路
因为杨辉三角是左右对称的,所以n最早出现的位置只能是左半部分。
每一行中越靠近中间的数越大,每一斜行中越往下越大。
所以从最下面的斜行往上枚举。
示意图:
代码
#include <iostream>
using namespace std;
typedef long long LL;
int n;
LL C(int a, int 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)
{
LL l = k * 2, r = n; // 每个斜行的第一个数是C(2k, k)依次为C(2k + 1, k)...
while (l < r) // 二分枚举
{
LL mid = l + r >> 1;
if (C(mid, k) >= n) r = mid; // 斜行中间的数大于n,则n在左半部分
else l = mid + 1; // 否则n在右半部分
}
if (l > r) return false; // 不在该斜行中
if (C(r, k) != n) return false; // 不在该斜行中
cout << r * (r + 1) / 2 + k + 1 << endl; // 输出答案
// C(r, k)前面有r行,1+2+3+...+r = r * (r + 1) / 2,k + 1是r行第k个数
return true;
}
int main()
{
cin >> n;
for (int k = 16; ; k--) // 从第16个斜行开始枚举
if (check(k)) // 找到了就停止
break;
return 0;
}