markdown复制## 1. 问题背景与需求分析
1073号题目"沙漏"是典型的算法图形输出类问题,这类题目在NOIP/CSP等编程竞赛中频繁出现。题目要求根据输入参数n(n≥3且为奇数),用指定字符(如'*')输出一个符合特定规律的沙漏图案。例如n=5时,输出如下图形:
code复制
这类题目的核心考察点在于:
1. 对循环结构的精准控制能力
2. 数学规律抽象与建模能力
3. 边界条件处理意识
4. 代码简洁性把控
实际工程中,类似原理可用于:
- 控制台界面设计
- 文本模式下的图形生成
- 打印格式控制
- 游戏中的ASCII艺术生成
## 2. 解题思路拆解
### 2.1 图形规律分析
观察n=5的案例,可以发现以下关键特征:
1. 总行数等于n(5行)
2. 每行字符数呈对称分布:5→3→1→3→5
3. 空格数呈0→1→2→1→0分布
4. 上下半区完全对称
数学关系推导:
- 设当前行号i(从0开始)
- 上半区(i≤n/2)时:
- 字符数 = n - 2*i
- 前导空格 = i
- 下半区(i>n/2)时:
- 字符数 = 2*(i-n/2)+1
- 前导空格 = n-1-i
### 2.2 算法选择考量
对比三种实现方案:
1. **纯数学计算法**:
- 优点:代码简洁
- 缺点:公式推导复杂
2. **对称镜像法**:
- 先处理上半区,下半区反向输出
- 优点:逻辑清晰
- 缺点:需要存储中间结果
3. **双指针控制法**:
- 用start/end指针控制字符范围
- 优点:无需存储,实时计算
- 缺点:边界条件复杂
经过实测,方案3在时间/空间复杂度上最优(均为O(n²)),适合竞赛场景。
## 3. 核心代码实现
### 3.1 基础版本实现
```cpp
#include <iostream>
using namespace std;
void printHourglass(int n, char c) {
int mid = n / 2;
for (int i = 0; i < n; i++) {
int spaces = (i <= m