CC++ & Algorithm

C++杨辉三角形

困难6
语言版本:C++Python
概述:用搭积木的方式理解杨辉三角形的规律,并学习用C++代码打印出这个神奇的数字三角形。

用C++打印杨辉三角形:像搭积木一样简单

想象一下,你有一堆积木,你想搭一个三角形。第一层放1块,第二层放2块,第三层放3块……但是杨辉三角形不是这样搭的。它的规律是:每一行最左边和最右边的数字都是1,中间的数字是它上面两个数字相加的和。就像一个数字金字塔,每个数字都由它“头顶上”的两个数字“生”出来。这种规律在生活中也很常见,比如你每天零花钱的组成:第一天有1元,第二天左边有1元、右边有1元,第三天中间的钱就是前两天相邻的钱加起来……神奇吧!

举个例子,杨辉三角形的前五行是这样的:

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1

你看第3行(1 2 1):中间那个2,是它头顶上左边的1和右边的1相加得到的(1+1=2)。第4行的3,是上面1和2相加(1+2=3),另一个3是2和1相加(2+1=3)。是不是很像搭积木,每一块都由下面两块支撑着?

杨辉三角形的规律:从搭积木到数学公式

杨辉三角形有两条重要的规律,我们用一个生活中的例子来理解:假设你要给全班同学发零食(每行代表一个小组的人数),最左边和最右边的同学总是拿到1颗糖,中间同学拿到的糖是“前面一排”里他左边和右边两位同学糖数之和。

规律1:每行第一个和最后一个数都是1
就像搭积木时,三角形的左右边框永远只放一块积木。在代码中,我们通过 y[i][0] = 1y[i][i] = 1 来实现。

规律2:中间的数等于它上方两个数之和
也就是 y[i][j] = y[i-1][j-1] + y[i-1][j]。这里的 i 表示行号(从0开始),j 表示列号(从0开始)。比如第4行第2列的数字“6”,它头顶上是第3行第1列的“3”和第3行第2列的“3”,相加得6。

用二维数组存储杨辉三角形

在C++里,我们可以用一个数组来存储这些数字。常用的方法是用一个二维数组,比如 int y[100][100]。为什么用二维数组?因为我们要记录行和列两个信息,就像班里的座位表,每个座位都有一个行号和列号。

把数组初始化为0是个好习惯——就像你先放一张空白纸,然后只把有数字的位置填上。下面这个表格展示了前4行在数组中的存放情况(行和列从0开始):

行\列0123
01
111
2121
31331

可以看到,每行只有 0i 这些列上有数字,其他位置还是0。打印时我们只打印 j <= i 的部分,这样就不会把多余的0打印出来。

完整代码示例(带详细注释)

下面这个代码可以让你输入行数,然后打印出杨辉三角形。每一行都加上了中文注释,方便理解。

#include <iostream>
using namespace std;

int main() {
    int n;                          // 存储用户输入的行数
    cout << "请输入杨辉三角形的行数:";
    cin >> n;

    int y[100][100] = {0};          // 定义二维数组,全部初始化为0

    // 第一步:生成杨辉三角形数据
    for (int i = 0; i < n; i++) {   // i表示当前行,从0开始
        y[i][0] = 1;                // 每行第一个数设为1
        y[i][i] = 1;                // 每行最后一个数设为1
        for (int j = 1; j < i; j++) { // j从1到i-1,处理中间的数字
            y[i][j] = y[i-1][j-1] + y[i-1][j]; // 中间数字等于上面两个之和
        }
    }

    // 第二步:打印杨辉三角形
    for (int i = 0; i < n; i++) {   // 遍历每一行
        for (int j = 0; j <= i; j++) { // 每行只打印到第i列
            cout << y[i][j] << " ";
        }
        cout << endl;               // 一行结束,换行
    }

    return 0;
}

运行这段代码,输入行数5,就会看到上面那个漂亮的数字金字塔。你可以改变n的值,生成任意行数的杨辉三角形。这个图案里藏着很多数学秘密,比如它跟组合数、二项式定理都有关系,以后我们会慢慢学到。

新手常犯的错误

  1. 数组越界:如果输入的行数n大于100,程序可能崩溃,因为数组大小只有100。可以加一个判断,或者把数组定义得更大(比如int y[1000][1000]),但更大的数组会占用更多内存。对中小学生来说,先保证n不超过100就好了。

  2. 忘记初始化数组:如果不用= {0}初始化,数组里可能有一些随机值,导致计算错误。一定要记得初始化!

  3. 打印时多了空格或者少了空格:上面的代码每两个数字之间有一个空格,行末没有多余空格。如果想更美观,可以在每行前面加一些空格让三角形居中,但这需要额外计算,比较麻烦。不过只要数据正确,空格多少不影响理解。

  4. 混淆行和列的编号:记住,数组 y[i][j] 中,i 是行号(从0开始),j 是列号(从0开始)。y[i][0] 是第 i 行最左边的数,y[i][i] 是第 i 行最右边的数。

相关指引

学会了杨辉三角形,你还可以去探索:

  • 组合数:杨辉三角形第 n 行第 m 个数等于 C(n, m)(从 n 个东西里选 m 个的方法数)。比如第4行第2个数是6,它表示 C(4,2)=6
  • 二项式定理(a+b)^n 展开后的系数就是杨辉三角形的第 n 行。
  • 打印其他图形:类似的方法可以打印乘法表、空心三角形等,都是利用循环和数组。

快动手试试,输入不同的行数,看看杨辉三角形能长到多大吧!

例题精讲

1单选题

杨辉三角形第6行所有数字之和是多少?(行号从1开始)

A16
B32
C64
D31
2单选题

以下C++代码打印杨辉三角形的前5行(行号从1开始),问第3行第2个数是多少? int a[6][6]={0}; for(int i=1;i<=5;i++){ a[i][1]=1; a[i][i]=1; } for(int i=3;i<=5;i++){ for(int j=2;j<i;j++){ a[i][j]=a[i-1][j-1]+a[i-1][j]; } } cout<<a[3][2]<<endl;

A1
B2
C3
D4
3判断题

杨辉三角形中,每个数等于它左边和右边两个数的和。

4填空题
以下代码用于输出杨辉三角形的前n行(n≤10),请补全空格处的内容。
#include <iostream>
using namespace std;
int main(){
    int n=5;
    int a[11][11]={0};
    for(int i=1;i<=n;i++){
        a[i][1]=1;
        a[i][i]=1;
    }
    for(int i=3;i<=n;i++){
        for(int j=2;j<___;j++){
            a[i][j]=a[i-1][j-1]+a[i-1][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            cout<<a[i][j]<<' ';
        }
        cout<<endl;
    }
    return 0;
}
5填空题
以下代码使用一维数组动态生成杨辉三角形的第n行(n≥1),请补全空格处的内容。
#include <iostream>
using namespace std;
int main(){
    int n=5;
    int a[20]={0};
    a[1]=1;
    for(int i=2;i<=n;i++){
        for(int j=i;j>=2;j--){
            a[j]=a[j]+___;
        }
    }
    for(int j=1;j<=n;j++) cout<<a[j]<<' ';
    return 0;
}