杨辉三角形C++ 蓝桥杯

在这里插入图片描述在这里插入图片描述

这个题我去年比赛的时候用的就是最笨的方法,开一个二位数组,然后逐个判断。

1、这个题我们到手先分析一波,这个数据范围是小于10的9次方,时间限制是1秒,杨辉三角有一个特性是每个数字都等于肩上两个数字之和,开个10亿*10亿的二位数组不可能,而且1秒最多操作1亿次,所以这个题目不能枚举,另有技巧。

在这里插入图片描述

2、我们可以通过杨辉三角判断一下我们需要枚举的行数范围,第n+1行第一个数字一定是1,第二个数字是n,第三个数字n*(n-1)/2,也就是说每一个数字n一定可以从第n+1行的第二个数字里找到他的位置,但不一定是杨辉三角里第一次出现,从第二列可以保证我们要找的数字n一定能在前n+1行内找到,但是枚举前n+1行肯定会超时,我们观察第三列,判断n*(n-1)/2>=10^9,粗略计算n>=44800,如果行数超过44800,那么该行的第三个数字肯定超过10亿,而且改行第四个数字、第五个数字…直到该行的一半数字都大于10亿(杨辉三角的每行都是对称的),都不是我们判断的数字范围,也无需我们再枚举,也就说我们需要枚举的行数只需要到44800行,如果在这44800行里没有找到n,那么n就默认在n+1行的第二个数字的位置。
3、没必要开个44800*44800的二位数组,我在这里用的是两行数组来回代替去更新。也可以用一行滚动数组去更新,但两行也没问题。再一个就是关注一下第i行第j列的数字的排列数的规律,还有就是要注意有的数字要开成long long更保险。

代码如下:

#include<bits/stdc++.h>  
using namespace std;
long long dp[2][44900];
int main()
{
	long long  n;
	cin>>n;
	if(n==1){
		cout<<1<<endl;
		return 0;
	} 
	dp[0][1]=1;
	int now=1;//now指向当前行 
	int last=0;//last指向上一行 
	long long sum=0;//数字的排列位 
	for(int i=2;i<=44800;i++){
		for(int j=1;j<=i;j++){
			dp[now][j]=dp[last][j]+dp[last][j-1];
			if(dp[now][j]==n){
				//cout<<i<<" "<<j<<endl;
				sum=(i-1)*i/2+j;
				cout<<sum<<endl;
				return 0;
			}
		}
		now=(now+1)%2;//更新一下 
		last=(last+1)%2;
	}
	sum=(n+1)*n/2+2;
	cout<<sum<<endl;
    return 0;
}
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值