第十二届蓝桥杯省赛第一场C++B组真题(杨辉三角形)

下面的图形是著名的杨辉三角形:

第十二届蓝桥杯省赛第一场C++B组真题(杨辉三角形)_第1张图片

如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:

1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, ...

给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?

输入格式

输入一个整数 N。

输出格式

输出一个整数代表答案。

数据范围

对于 20%的评测用例,1≤N≤10;
对于所有评测用例,1≤N≤10^9。

输入样例:

6

输出样例:

13

杨辉三角的一些性质:左右对称,所以只要在杨辉三角右半边出现过的数都会在左半边出现过,且位置是对称的,所以答案一定是在左半边,还有就是对于每一斜行和竖行从上至下是依次增大的,需要明确的一点是所有的数都会在杨辉三角中出现,比如x,一定会有C(x,1)对应于x,所以不用担心有无解的情况,但是我们需要找到数值为x的最靠上的位置就需要从下往上枚举,因为如果x第一次出现在(i,j)这个位置,那么这个位置左上和上方以及右上的数都会比x要小,所以我们可以枚举斜行,利用二分来枚举在每一斜行中出现的位置即可,注意是从下往上枚举:

代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
ll C(ll a,ll b)//求组合数 
{
    ll ans=1;
    for(int i=a,j=1;j<=b;i--,j++)
        ans*=i,ans/=j;
    return ans;
}
ll n;
bool check(int k)//枚举第k斜行 
{
    ll l=2*k,r=max(l,n);
    while(l>1;
        if(C(mid,k)>=n) r=mid;
        else l=mid+1;
    }
    if(C(l,k)==n)
    {
        printf("%lld",l*(l+1)/2+k+1);//注意组合数是从C(0,0)开始的 
        return true;
    }
    return false;
}
int main()
{
    cin>>n;
    for(int i=16;;i--)//枚举斜行 
        if(check(i)) break;
    return 0;
}

你可能感兴趣的:(蓝桥杯备考,蓝桥杯)