题解:洛谷 P5725 求三角形

【题目来源】

洛谷:P5725 【深基4.习8】求三角形 - 洛谷

【题目描述】

模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。

【输入】

输入矩阵的规模,不超过 \(9\)

【输出】

输出矩形和正方形

【输入样例】

4

【输出样例】

01020304
05060708
09101112
13141516

      01
    0203
  040506
07080910

【核心思想】

  1. 问题分析:给定一个规模 \(n\)\(n \le 9\)),要求输出两个图形:一个 \(n \times n\) 的数字方阵,以及一个右对齐的数字直角三角形。所有数字均需按两位格式输出(不足两位时补前导零),且两个图形之间有一个空行。本质是按照固定格式进行数字填充与打印的模拟,关键在于控制数字的递增、每行宽度以及空格的数量。

  2. 算法选择

    • 双重循环 + 格式化输出:分别用两层嵌套循环控制行和列。第一部分按行优先顺序递增打印 \(n^2\) 个两位数字;第二部分则每行先打印一定数量的空格(两个空格一组),再打印递增的数字,行 \(i\) 的数字个数为 \(i\)
  3. 关键步骤

    • 读入与初始化:读取 \(n\),初始化数字计数器 mark = 0
    • 打印正方形
      • 外层循环 \(i\) 从 1 到 \(n\)(行)。
      • 内层循环 \(j\) 从 1 到 \(n\)(列):mark++,以两位格式输出 mark(若 mark < 10 则先输出 0)。
      • 每行结束后换行。
    • 打印空行:输出一个换行。
    • 打印三角形
      • 重置 mark = 1
      • 外层循环 \(i\) 从 1 到 \(n\)(行):
        • 先打印 \(n-i\) 组两个空格(用于右对齐)。
        • 内层循环 \(j\) 从 1 到 \(i\)(列):以两位格式输出 mark,然后 mark++
        • 每行结束后换行。
    • 输出:按要求输出图形。
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n^2)\),因为两部分各输出约 \(n^2/2\) 个数字,\(n \le 9\),常数级操作。
    • 空间复杂度:\(O(1)\),只使用了常数个变量。
  5. 模拟与控制

    • 两位数字格式:由于 \(n^2 \le 81\),所有数字最大为两位数,因此只需判断 mark < 10 时补一个前导零即可。
    • 三角形缩进:每行前面的空格数为 \(2 \times (n - i)\),因为每个数字占两位,所以每组空格也是两个空格字符。代码中用 cout << " " 实现。
    • 数字连续性:整个过程中 mark 在正方形和三角形中分别独立递增,正方形从 1 到 \(n^2\),三角形从 1 到 \(n(n+1)/2\)
    • 适用场景:这类格式化输出问题常见于编程入门训练,核心是熟悉循环嵌套和输出控制。

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

/**
 * 主函数 - 程序入口
 * @return 程序执行状态码(0表示成功)
 */
int main()
{
    int n;               // 定义变量:矩阵的维度
    int mark = 0;        // 定义变量:当前数字计数器

    cin >> n;            // 输入矩阵维度n

    // 第一部分:打印n×n的数字矩阵
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            mark++;               // 数字递增
            if (mark < 10)        // 数字小于10时补零
                cout << 0;
            cout << mark;         // 输出当前数字
        }
        cout << endl;             // 每行结束换行
    }

    cout << endl;                 // 两个图形之间空一行

    // 第二部分:打印数字金字塔
    mark = 1;                     // 重置计数器
    for (int i = 1; i <= n; i++)
    {
        // 打印前导空格(用于右对齐)
        for (int j = 1; j <= n - i; j++)
        {
            cout << "  ";         // 每个数字占2位,所以空格也是2位
        }

        // 打印当前行的数字
        for (int j = 1; j <= i; j++)
        {
            if (mark < 10)        // 数字小于10时补零
                cout << 0;
            cout << mark;         // 输出当前数字
            mark++;               // 数字递增
        }
        cout << endl;             // 每行结束换行
    }

    return 0;                     // 程序正常结束
}

【输出样例】

01020304
05060708
09101112
13141516

      01
    0203
  040506
07080910
posted @ 2026-08-31 09:27  团爸讲算法  阅读(14)  评论(0)    收藏  举报