2021蓝桥杯杨辉三角形
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列: 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1…
给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?
输入描述
输入一个整数 N。
输出描述
输出一个整数代表答案。
对于所有评测用例,1≤N≤1000000000。
分析
首先明确杨辉三角形中的第i行第j列的数为
C
i
j
C_{i}^{j}
Cij(i从0开始,j也从0开始)
由于我们求整数N第一次出现的位置,那么该位置一定在杨辉三角形的左边一半。所以我们将杨辉三角形取左边一半
我们通过观察可以得知,在一行中,越往左数越小,在一列中,越往上数越小,并且一行中最大值一定是在中间,即第i行的最大值在第i/2列,我们通过excel计算得到
C
32
16
C_{32}^{16}
C3216<1000000000<
C
33
16
C_{33}^{16}
C3316
那么所给数据的所在位置最大不会超过16列,所以我们从第16列开始,从右往左对行进行二分查找。
代码中要注意的有二分查找左端点初始化时必须是列数*2,因为左端点如果从0开始,有很多行是不存在我们正在循环的这一列的。
完整代码如下
#include <iostream>
using namespace std;
long long n;
long long res(long long i,int j) //函数计算第i行第j列数
{
long long tn=1;
for(long long a=i,b=1;b<=j;a--,b++)
{
tn=a * tn / b;
if(tn>n) return tn;
}
return tn;
}
int main()
{
long long result=0;
cin>>n;
for( int i=16;i>=0;i--)
{
long long l=i*2;
long long r=n;
long long mid=0;
while(l<=r){
mid=l+(r-l)/2;
result=res(mid,i);
if(result==n) break;
else if(result>n) r=mid-1;
else l=mid+1;
}
if(result==n)
{
long long re=mid*(mid+1)/2+i+1;
cout<<re;
break;
}
}
return 0;
}
excel中计算组合数和排列数方法,蓝桥杯考试中可用
计算组合
=COMBIN()
计算排列
=PERMUT()
##结语
本题对杨辉三角的性质有比较深刻的应用
本人知识有限,如果各位发现有什么问题或者更好的解法,欢迎在评论区指正。