题解:学而思编程 打印K型图案

【题目来源】

学而思编程:打印K型图案

【题目描述】

小X想用 * 打出一个大写的 \(K\) 字形图案。例如:

\(n=2\) 时的"K"型图案:

\(n=3\) 时的"K"型图案:

给定一个整数 \(n\) 表示图案规模的大小。请输出一个由星号组成的,对应大小的 \(K\) 字形图案。

【输入】

一行一个整数 \(n\)

【输出】

输出对应的"K"型图案。

【输入样例】

4

【输出样例】

**    ****
**   ***
**  **
** *
***
** *
**  **
**   ***
**    ****

【核心思想】

  1. 问题分析:给定整数 \(n\),输出一个由 * 组成的 \(K\) 字形图案。图案由三部分构成:上半部分(向右下方倾斜)、中间分隔行(水平连接)、下半部分(向右上方倾斜)。这是一个规律模拟问题,关键在于分析图案各部分的几何规律并用循环精确控制每行的 * 和空格数量。

  2. 算法选择

    • 分块构造法:将 \(K\) 字图案拆解为上半三角形、中间行、下半三角形三个独立模块分别构造
    • 规律映射:通过行号 \(i\) 建立各模块中空格数与星号数的数学映射关系
  3. 关键步骤

    • 读取输入:读取图案规模参数 \(n\)
    • 计算固定宽度\(w = (n+1)/2\),表示 \(K\) 字左侧竖线的宽度(即每行第一组 * 的固定数量)
    • 上半部分(共 \(n\) 行,行号 \(i\)\(1\)\(n\)):
      • 固定输出 \(w\)*(左侧竖线)
      • 输出空格:数量从 \(n\) 递减到 \(1\),即循环 \(j\)\(i\)\(n\),输出 \(n - i + 1\) 个空格
      • 输出第二组 *:数量从 \(n\) 递减到 \(1\),与空格同步递减,即 \(n - i + 1\)*
    • 中间分隔行
      • 输出 \(w + 1\)*,作为上下两部分的连接横线
    • 下半部分(共 \(n\) 行,行号 \(i\)\(1\)\(n\)):
      • 固定输出 \(w\)*(左侧竖线)
      • 输出空格:数量从 \(1\) 递增到 \(n\),即循环 \(j\)\(1\)\(i\),输出 \(i\) 个空格
      • 输出第二组 *:数量从 \(1\) 递增到 \(n\),与空格同步递增,即 \(i\)*
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n^2)\),共输出 \(2n + 1\) 行,每行字符数约为 \(O(n)\),总字符量与图案面积成正比
    • 空间复杂度:\(O(1)\),仅使用常数个循环变量,逐行输出无需存储整个图案
  5. 规律模拟的核心思想

    • 几何分解:将复杂图案拆分为上下对称的两个三角形加一个中间行,降低分析难度
    • 同步变化:上半部分中,空格数与右侧 * 数同步从 \(n\) 递减到 \(1\);下半部分同步从 \(1\) 递增到 \(n\)。利用同一循环变量控制两者,保证对齐
    • 固定与变化分离:左侧竖线宽度 \(w = (n+1)/2\) 固定不变,与变化的右侧部分解耦,使结构清晰
    • 行号映射:通过行号 \(i\) 建立"当前行位置 → 空格数/ * 数"的线性映射,避免硬编码
    • 适用于图形规律输出、矩阵构造、模式打印类问题

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n;  // 控制图案大小的参数

int main()
{
    cin >> n;  // 输入参数n

    // 上半部分三角形
    for (int i = 1; i <= n; i++)  // 行循环,共n行
    {
        // 第一组星号:固定宽度 (n+1)/2
        for (int j = 1; j <= (n+1)/2; j++)
        {
            cout << "*";
        }

        // 空格:数量从n递减到1
        for (int j = i; j <= n; j++)
        {
            cout << " ";
        }

        // 第二组星号:数量从n递减到1
        for (int j = i; j <= n; j++)
        {
            cout << "*";
        }

        cout << endl;  // 换行
    }

    // 中间分隔行
    for (int i = 1; i <= (n+1)/2 + 1; i++)
    {
        cout << "*";
    }
    cout << endl;

    // 下半部分三角形
    for (int i = 1; i <= n; i++)  // 行循环,共n行
    {
        // 第一组星号:固定宽度 (n+1)/2
        for (int j = 1; j <= (n+1)/2; j++)
        {
            cout << "*";
        }

        // 空格:数量从1递增到n
        for (int j = 1; j <= i; j++)
        {
            cout << " ";
        }

        // 第二组星号:数量从1递增到n
        for (int j = 1; j <= i; j++)
        {
            cout << "*";
        }

        cout << endl;  // 换行
    }

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

【运行结果】

4
**    ****
**   ***
**  **
** *
***
** *
**  **
**   ***
**    ****
posted @ 2026-07-05 16:04  团爸讲算法  阅读(7)  评论(0)    收藏  举报