题解:学而思编程 打印K型图案
【题目来源】
学而思编程:打印K型图案
【题目描述】
小X想用 * 打出一个大写的 \(K\) 字形图案。例如:
\(n=2\) 时的"K"型图案:

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

给定一个整数 \(n\) 表示图案规模的大小。请输出一个由星号组成的,对应大小的 \(K\) 字形图案。
【输入】
一行一个整数 \(n\)。
【输出】
输出对应的"K"型图案。
【输入样例】
4
【输出样例】
** ****
** ***
** **
** *
***
** *
** **
** ***
** ****
【核心思想】
-
问题分析:给定整数 \(n\),输出一个由
*组成的 \(K\) 字形图案。图案由三部分构成:上半部分(向右下方倾斜)、中间分隔行(水平连接)、下半部分(向右上方倾斜)。这是一个规律模拟问题,关键在于分析图案各部分的几何规律并用循环精确控制每行的*和空格数量。 -
算法选择:
- 分块构造法:将 \(K\) 字图案拆解为上半三角形、中间行、下半三角形三个独立模块分别构造
- 规律映射:通过行号 \(i\) 建立各模块中空格数与星号数的数学映射关系
-
关键步骤:
- 读取输入:读取图案规模参数 \(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\) 个
- 中间分隔行:
- 输出 \(w + 1\) 个
*,作为上下两部分的连接横线
- 输出 \(w + 1\) 个
- 下半部分(共 \(n\) 行,行号 \(i\) 从 \(1\) 到 \(n\)):
- 固定输出 \(w\) 个
*(左侧竖线) - 输出空格:数量从 \(1\) 递增到 \(n\),即循环 \(j\) 从 \(1\) 到 \(i\),输出 \(i\) 个空格
- 输出第二组
*:数量从 \(1\) 递增到 \(n\),与空格同步递增,即 \(i\) 个*
- 固定输出 \(w\) 个
-
时间/空间复杂度:
- 时间复杂度:\(O(n^2)\),共输出 \(2n + 1\) 行,每行字符数约为 \(O(n)\),总字符量与图案面积成正比
- 空间复杂度:\(O(1)\),仅使用常数个循环变量,逐行输出无需存储整个图案
-
规律模拟的核心思想:
- 几何分解:将复杂图案拆分为上下对称的两个三角形加一个中间行,降低分析难度
- 同步变化:上半部分中,空格数与右侧
*数同步从 \(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
** ****
** ***
** **
** *
***
** *
** **
** ***
** ****
浙公网安备 33010602011771号