蓝桥杯历届真题 杨辉三角形【第十二届】【省赛】【B组】

8 篇文章 0 订阅
7 篇文章 0 订阅

蓝桥杯历届真题 杨辉三角形【第十二届】【省赛】【B组】

题目链接-蓝桥杯历届真题 杨辉三角形在这里插入图片描述在这里插入图片描述

题目大意
将杨辉三角形按照从上到下、从左至右的顺序排成一个数列。输入一个正整数 N N N,请你判断该数列中第一次出现 N N N是数列中第几个数。
解题思路

  • 思路一

    找 规 律 找规律
          1 1 1
          1 1 1   1 1 1
          1 1 1   2 2 2   1 1 1
          1 1 1   3 3 3   3 3 3   1 1 1
          1 1 1   4 4 4   6 6 6   4 4 4   1 1 1
          1 1 1   5 5 5   10 10 10   10 10 10   5 5 5   1 1 1

  1. 观察上面杨辉三角形,可以发现第一列全是 1 1 1,第二列为从 0 0 0开始每次递增 1 1 1的递增序列,第三列为序列 1 、 2 、 3 … n 1、2、3…n 123n(即第二列)的前缀和序列。

  2. 由于 N N N的最大是 1 e 9 1e9 1e9,第一列全为 1 1 1,不用考虑,第二列每次递增 1 1 1,若要达到最大值,定义数组的内存肯定超限。然后第三列通过计算 n ∗ ( n + 1 ) / 2 > 1 e 9 n*(n+1)/2>1e9 n(n+1)/2>1e9可以得到 n > 44721 n>44721 n>44721,由于第三列第一行和第二行都为 0 0 0,所以最小需要44723行。

  3. 当第三列的值已经大于 1 e 9 1e9 1e9时,不需要再计算后面的数,直接根据第二列规律,找第二列中 n n n的位置即可。由于第二列是从 0 0 0开始的,此时可以确定 n n n是在第 n + 1 n+1 n+1行,又因为是第二列,所以 n n n的是数列中第 n ∗ ( n + 1 ) / 2 + 2 n*(n+1)/2+2 n(n+1)/2+2个。

    附上代码

    #pragma GCC optimize("-Ofast","-funroll-all-loops")
    #include<bits/stdc++.h>
    #define int long long
    #define lowbit(x) (x &(-x))
    #define endl '\n'
    #define debug(x) cout<<"# "<<x<<endl;
    using namespace std;
    const int INF=0x3f3f3f3f3f3f3f3f;
    const int dir[4][2]={-1,0,1,0,0,-1,0,1};
    const double PI=acos(-1.0);
    const double e=exp(1.0);
    const double eps=1e-10;
    const int M=1e9+7;
    const int N=2e5+10;
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef unsigned long long ull;
    int a[N];
    signed main(){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    
    	int n,k=1;
    	cin>>n;
    	a[0]=1;
    	if(n==1) cout<<1<<endl;
    	else{
    		for(int i=1;i<44725;i++){
    			for(int j=i;j>=1;j--){
    				a[j]+=a[j-1];
    				if(a[j]==n){
    					cout<<k+i-j+1<<endl;
    					return 0;
    				}
    			}
    			k+=(i+1);
    		}
    		cout<<(1+n)*n/2+2<<endl;
    	}
    	return 0;
    }
    
  • 思路二
    二 分 + 组 合 数 二分+组合数 +
  1. 根据杨辉三角形与组合数的联系,第 i i i行第 j j j列的数都是组合数 C ( i , j ) C(i, j) C(i,j),因为 C ( n , 1 ) = n C(n, 1) = n C(n,1)=n,所以对于每个输入的 n n n必定有解。

  2. 由于杨辉三角形是左右对称的,且数列是按照每行从左到右排列的,所以数字第一次出现必定在左边。
            1 1 1
           1 1 1
          1 1 1 2
         1 1 1 3
        1 1 1 4 6
       1 1 1 5 10
    1 1 1 6 15 20

  3. 根据题意 n n n最大 1 e 9 1e9 1e9,且 C ( 34 , 17 ) > 1 e 9 C(34, 17) > 1e9 C(34,17)>1e9 C ( 32 , 16 ) < 1 e 9 C(32, 16) < 1e9 C(32,16)<1e9,因此只要枚举前 16 16 16个斜行即可

  4. 观察上面三角形可以看出,除了第一条边,一条边上的数都是严格单调递增的,所以我们可以对每一条边进行一次二分操作

  5. 组合数计算需要用数学公式 C ( n , m ) = n ! ( n − m ) ! ∗ m ! = ( n − m + 1 ) ( n − m + 2 ) ∗ … ∗ n 1 ∗ 2 ∗ … ∗ m C(n,m)=\frac{n!}{(n-m)!*m!}=\frac{(n-m+1)(n-m+2)*…*n}{1*2*…*m} C(n,m)=(nm)!m!n!=12m(nm+1)(nm+2)n直接算,如果数组的话会超内存。
    附上代码

    #pragma GCC optimize("-Ofast","-funroll-all-loops")
    #include<bits/stdc++.h>
    #define int long long
    #define lowbit(x) (x &(-x))
    #define endl '\n'
    #define debug(x) cout<<"# "<<x<<endl;
    using namespace std;
    const int INF=0x3f3f3f3f3f3f3f3f;
    const int dir[4][2]={-1,0,1,0,0,-1,0,1};
    const double PI=acos(-1.0);
    const double e=exp(1.0);
    const double eps=1e-10;
    const int M=1e9+7;
    const int N=2e3+10;
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef unsigned long long ull;
    int C(int a,int b,int n){
    	int ans=1;
    	for(int i=a,j=1;j<=b;i--,j++){
    		ans=ans*i/j;
    		if(ans>n) return ans;
    	}
    	return ans;
    }
    bool check(int k,int n){
    	int l=2*k,r=max(n,l);
    	while(l<r){
    		int mid=(l+r)/2;
    		if(C(mid,k,n)>=n) r=mid;
    		else l=mid+1;
    	}
    	if(C(r,k,n)!=n) return false;
    	cout<<(r+1)*r/2+k+1<<endl;
    	return true;
    }
    signed main(){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    
    	int n;
    	cin>>n;
    	for(int i=16;i>=0;i--){
    		if(check(i,n)) break;
    	}
    	return 0;
    }
    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目描述: 给定一个正整数n,输出杨辉三角形的前n行。 输入格式: 输入一个正整数n。 输出格式: 输出杨辉三角形的前n行,每行数字之间用一个空格隔开。 样例输入: 5 样例输出: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 数据范围: 1≤n≤34 解题思路: 杨辉三角形的每一行都可以看成是一个二项式系数,第i行第j个数表示为C(i-1,j-1),可以通过递推公式C(i,j)=C(i-1,j-1)+C(i-1,j)来求得。 代码实现: ### 回答2: 杨辉三角形是一种数学规律,由中国古代数学家杨辉发现而得名,又称杨辉图。在数学中,杨辉三角形是一个数表,其中每个数是由上方两数相加而来。它起初只是用于排列合的计算,但它的性质也使它成为了许多数学领域的重要工具。 该题中要求实现杨辉三角形的生成,并输出第 n 行第 k 项的值。这题使用的是合数的性质:杨辉三角形的第 n 行第 k 个数就是合数 $C_{n-1}^{k-1}$。 因此,我们可以很容易地实现对杨辉三角形的生成,只需要使用两重循环即可,复杂度为 $O(n^2)$。而输出第 n 行第 k 个数的值则只需要计算合数 $C_{n-1}^{k-1}$ 即可,这可以使用递推公式求数合数来完成,复杂度为 $O(n)$,因此总时间复杂度为 $O(n^2)$。 此外,在实现过程中,还需要注意一些细节,如数下标的问题,以及输入输出格式的要求等。 总之,这道题要求我们掌握杨辉三角形的生成和合数的计算方法,以及一些基本的编程技巧,能够灵活运用循环和递推等方法解决问题。掌握这些知识和技巧不仅可以帮助我们解决这道题,也能帮助我们解决其他相关的数学和编程问题。 ### 回答3: 这道题为杨辉三角形,要求输出p行杨辉三角形的前n项之和。杨辉三角形是中学数学中的常见概念,在数学上有重要应用。开始时,我们先输入测试数据,其中包括P、n和杨辉三角形。然后,我们就要开始对数据进行处理。首先,我们要创建一个二维数来存储杨辉三角形中的每个元素,并对其进行初始化。 其次,我们需要使用嵌套的for循环来填充数。外层循环用来遍历杨辉三角形的每一行,内层循环则用来填充每一行的元素。填充的方法是通过将上一行相邻元素相加的方式来得到当前行的元素。每行第一个和最后一个元素都为1。在填充完杨辉三角形后,我们通过for循环来输出前n项的和,最后将结果返回。 需要注意的是,在处理数据时要注意异常情况,例如P、n的取值范围以及杨辉三角形的格式是否正确等。 总体来说,这道题需要我们掌握二维数和嵌套循环的使用方法,并要注意输入输出的格式。可以通过多练习类似的题目来加深对知识点的理解和熟练度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值