题目链接 >> https://www.luogu.com.cn/problem/P8749
这道题呐!洛谷题解区虽然只有两篇题解,严格来说是一篇,但我承认人家的质量是真的高真的用心[手动小花花]
纯暴力确实只能拿20分,不管是MEL了,还是TLE了,都是20分,一视同仁/(ㄒoㄒ)/~~
相比洛谷中佬的题解,多了一些自己的注释~~~
#include <bits/stdc++.h>
using namespace std;
#define int long long
int nn, anx;
int c(int n, int k) // 行和对角线的列,都是从0开始哒!
{
anx = 1;
for (int i = n, j = 1; j <= k; i--, j++)
{
anx = anx * i / j;//防止数据溢出longlong,所以边乘边除
if (anx > nn)
return anx;//及时止损喽!防止数据溢出喽
}
return anx;
}
signed main()
{
cin >> nn;
if (nn == 1)
{
cout << 1;
return 0;
}
for (int i = 18; i >= 0; i--)
{
int r = 1e9, l = i*2, lim = 0, mid = 0;
//这里l之所以等于二,咱们画个图就知道了
//咱们取的是整个杨辉三角的一半(加中间的那个数)
//所以最小最小不会低于列,也就是i的两倍 <--- c(2*i,i);
//画个图写杨辉三角中每个数的坐标就显而易见了,吧~(¯▽¯~)
while (l < r)//这里仍然是使用y总基础课的二分方法,洛谷题解区的二分我建议小白看看
{//因为y总没有while中相等的情况,也就是l<=r或l>=r的等号情况
mid = (l + r) >> 1, lim = c(mid, i);
if (lim == nn){
cout << (mid + 1) * mid / 2 + i + 1;
return 0;
}
else if (lim > nn)
r = mid;
else
l = mid + 1;
}
}
return 0;
}