【C++】P5732 【深基5.习7】杨辉三角

news/2025/1/8 3:59:05/

在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
    • 输入输出格式
      • 输入
      • 输出
    • 输入输出样例
  • 💯我的实现方法
    • 实现解析
    • 实现的优点
    • 改进空间
  • 💯老师的实现方法
    • 实现解析
    • 优缺点对比
  • 💯优化与扩展
    • 方案 1:使用一维数组
    • 优点
    • 方案 2:只使用一个数组
    • 优点
  • 💯总结


在这里插入图片描述


💯前言

  • 杨辉三角,又称帕斯卡三角,是数学中的一个经典模型,它不仅具有简单的构造规律,而且在数学和计算机科学中有着广泛的应用。例如,杨辉三角可以用于计算组合数、展开二项式、递归问题等。在编程学习中,杨辉三角是一个非常适合用来练习数组、循环、条件判断和动态规划的例题。
    本文以一道洛谷题目 P5732 为切入点,结合代码分析,详细讲解如何构造杨辉三角,并对比了不同的实现方式,包括初学者的实现和优化的写法。最后,还探讨了内存优化和动态数组的使用。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

P5732 【深基5.习7】杨辉三角
在这里插入图片描述
题目要求实现一个程序,输入一个整数 n n n 1 ≤ n ≤ 20 1 \leq n \leq 20 1n20),输出杨辉三角的前 n n n 行。具体规则如下:

  1. 杨辉三角的每一行的开头和结尾都是 1
  2. 每个非首尾的数字等于上一行相邻两个数字之和;

输入输出格式

输入

无(直接读取用户输入的 n n n)。

输出

无(直接打印杨辉三角的前 n n n 行)。

输入输出样例

输入:

6

输出:

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

💯我的实现方法

首先,让我们来看我对该题目的实现代码:

#include <iostream>
using namespace std;int main()
{int n;cin >> n;int arr[n][n];for (int i = 0; i < n; i++){arr[i][0] = 1;arr[i][i] = 1;for (int j = 1; j < i; j++){arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];}}for (int i = 0; i < n; i++){for (int j = 0; j <= i; j++){cout << arr[i][j] << " ";}cout << endl;}return 0;
}

在这里插入图片描述

实现解析

  1. 二维数组的声明:

    int arr[n][n];
    
    • 用二维数组 arr 来存储杨辉三角的每个数值,其中第 i i i 行的前 i + 1 i+1 i+1 个元素是有效的。
    • 这种实现的缺点是多余的内存浪费:实际上,每一行需要存储的元素个数等于行号,而多余的部分(右侧无效的元素)不会被使用。
  2. 杨辉三角的构造规则:

    • 首尾元素:
      arr[i][0] = 1;
      arr[i][i] = 1;
      
      每一行的第一个和最后一个元素始终为 1
    • 中间元素:
      arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
      
      每个非首尾元素等于上一行左上方和正上方两个元素之和。
  3. 输出部分:

    • 使用两层循环,逐行打印数组中有效的元素:
      for (int i = 0; i < n; i++) {for (int j = 0; j <= i; j++) {cout << arr[i][j] << " ";}cout << endl;
      }
      

实现的优点

  • 逻辑清晰:按照杨辉三角的定义逐步构造,代码结构简单明了。
  • 动态规划思想:当前行依赖于上一行,避免了重复计算。

改进空间

  • 空间浪费:二维数组中有许多无效的元素(右侧未使用的部分)。
  • 灵活性较低:使用固定大小的二维数组 arr[n][n],当 n n n 较大时可能导致栈溢出。

💯老师的实现方法

接下来,让我们分析老师提供的代码:

#include <iostream>
using namespace std;const int N = 25;
int arr[N][N];int main()
{int n = 0;cin >> n;for (int i = 0; i < n; i++){for (int j = 0; j <= i; j++){if (j == 0 || i == j)arr[i][j] = 1;if (i >= 2 && j >= 1)arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];cout << arr[i][j] << " ";}cout << endl;}return 0;
}

在这里插入图片描述

实现解析

  1. 全局数组的使用:

    const int N = 25;
    int arr[N][N];
    
    • 老师直接在全局中声明了一个最大容量为 25 × 25 25\times25 25×25 的二维数组,避免了栈空间不足的问题。
    • 这种实现方法适合小规模问题,但对于大规模问题(如 n > 25 n>25 n>25)无法扩展。
  2. 优化的构造规则:

    • 使用条件判断处理首尾元素和中间元素:
      if (j == 0 || i == j)arr[i][j] = 1;
      if (i >= 2 && j >= 1)arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
      
      这种写法简洁高效,避免了不必要的赋值操作。
  3. 输出部分的优化:

    • 直接在构造数组的同时输出每个元素:
      cout << arr[i][j] << " ";
      
      这种方法节省了额外的循环遍历时间。

优缺点对比

  • 优点:
    • 使用全局数组避免栈溢出。
    • 通过条件判断简化了逻辑,减少了多余的赋值操作。
    • 构造和输出合并,代码更加紧凑。
  • 缺点:
    • 与我的实现一样,存在空间浪费问题。
    • 不够灵活,无法支持动态规模的输入。

💯优化与扩展

为了进一步提高代码的效率和灵活性,我们可以考虑以下优化方案:

方案 1:使用一维数组

杨辉三角每一行只依赖于上一行的结果,因此可以用一维数组代替二维数组,从而节省空间。

优化代码如下:

#include <iostream>
#include <vector>
using namespace std;int main()
{int n;cin >> n;vector<int> prev, curr;for (int i = 0; i < n; i++) {curr.resize(i + 1);curr[0] = curr[i] = 1; // 首尾元素置为1for (int j = 1; j < i; j++) {curr[j] = prev[j - 1] + prev[j]; // 中间元素计算}prev = curr; // 保存当前行,用于下一行计算for (int num : curr) cout << num << " ";cout << endl;}return 0;
}

在这里插入图片描述

优点

  • 节省空间:只需要两个一维数组存储当前行和上一行。
  • 动态性强:使用 vector,可以支持任意大小的输入。

方案 2:只使用一个数组

进一步优化空间,可以只使用一个数组,同时更新当前行和上一行的值。

优化代码如下:

#include <iostream>
#include <vector>
using namespace std;int main()
{int n;cin >> n;vector<int> arr(n, 0);for (int i = 0; i < n; i++) {arr[i] = 1;for (int j = i - 1; j > 0; j--) {arr[j] += arr[j - 1];}for (int k = 0; k <= i; k++) {cout << arr[k] << " ";}cout << endl;}return 0;
}

在这里插入图片描述

优点

  • 极致节约空间:只用一个数组完成计算和输出。
  • 效率较高:内层循环从右向左更新,避免了值被覆盖。

💯总结

通过对题目、我的实现、老师的实现以及优化方案的全面分析,我们可以清晰地看到实现杨辉三角的方法从最简单的二维数组,到一维数组的优化,再到极致的单数组实现,体现了编程中 “空间换时间” 和 “逐步优化” 的思想。

无论是初学者学习二维数组的基础操作,还是深入研究动态规划的高效实现,这道题都提供了非常好的练习机会。希望通过本文的讲解,读者不仅能掌握杨辉三角的构造方法,还能学会分析和优化代码的技巧。


在这里插入图片描述


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


http://www.ppmy.cn/news/1561453.html

相关文章

【商城的功能开发】

商城的功能开发是一个复杂且多方面的过程&#xff0c;涉及前端和后端的开发、用户界面设计、数据库管理、支付系统集成等多个环节。以下是一些关键功能和步骤&#xff0c;可以帮助你了解商城开发的基本流程&#xff1a; 一、需求分析 目标用户&#xff1a;确定目标市场和用户需…

Redis 实现分布式锁

文章目录 引言一、Redis的两种原子操作1.1 Redis 的原子性1.2 单命令1.3 Lua 脚本1.4 对比单命令与 Lua 脚本 二、Redis 实现分布式锁2.1 分布式锁的概念与需求2.1.1 什么是分布式锁&#xff1f;2.1.2 分布式锁的常见应用场景 2.2 基于 Redis 的分布式锁实现2.2.1 锁的获取与释…

CPU过剩是什么意思? 有什么对电脑的影响吗?如何确认CPU有没有过剩

CPU 过剩通常是指计算机系统中 CPU 的性能远远超出了当前运行任务的需求。以下从产生原因和对电脑的影响为你详细介绍&#xff1a; 产生原因 硬件升级与软件发展不同步&#xff1a;用户为追求高性能提前升级了 CPU&#xff0c;而当前的软件应用程序在算法和功能上没有太大突破&…

用python编写一个放烟花的小程序

import pygame import random # 代码解释及使用说明&#xff1a; # 首先&#xff0c;导入 pygame 和 random 库。pygame 用于创建游戏窗口和图形绘制&#xff0c;random 用于生成随机数。 # 初始化 pygame&#xff0c;并设置屏幕尺寸为 800x600 像素&#xff0c;设置窗口标题为…

CSS——14.交集选择器

选择既要满足div元素又要满足 类名为abc的元素 即只要这个元素&#xff1a;< div class“abc”>我爱学习2< /div >变红&#xff0c;无论是单独使用div标签选择器还是单独使用 ".abc"类选择器都无法实现只让< div class“abc”>我爱学习2< /div …

kubelet状态错误报错

journalctl -xeu kubelet 执行后的日志如下: -- -- The process exit code is exited and its exit status is 1. Jan 02 14:20:06 iv-ydipyqxfr4wuxjsij0bd systemd[1]: kubelet.service: Failed with result exit-code. -- Subject: Unit failed -- Defined-By: system…

df.replace({‘b‘: r‘\s*(\.)\s*‘}, {‘b‘: r‘\1ty‘}, regex=True)

这段代码 df.replace({b: r\s*(\.)\s*}, {b: r\1ty}, regexTrue) 用于在 DataFrame 中进行替换操作&#xff0c;具体来说是针对 b 列&#xff0c;匹配并替换符合正则表达式的值。 详细解析&#xff1a; df.replace()&#xff1a;这是 Pandas 中的 replace() 方法&#xff0c;用…

【服务器常见网络攻击】

服务器常见网络攻击 服务器遭受的网络攻击类型繁多&#xff0c;每种攻击都有其特定的技术特征和应对策略。 1. DDoS&#xff08;分布式拒绝服务&#xff09;攻击 描述&#xff1a;攻击者通过控制大量计算机&#xff08;僵尸网络&#xff09;向目标服务器发送过多请求&#x…