202606-菱形(luogu-B4554)
GESP C++二级,2026年6月真题,嵌套循环与字符图形绘制,难度⭐⭐,洛谷难度普及-。
luogu-B4554 [GESP202606 二级] 菱形
题目要求
题目描述
给定正整数 ,在 个网格的画布中,使用字符画一个边长为 个网格的菱形。其中,空白网格使用 表示,菱形边所在的网格用 表示。
例如当 时,图形如下:
..+.. .+.+. +...+ .+.+. ..+..
输入格式
输入一个正整数 。
输出格式
输出 行,表示按要求画的菱形。
输入输出样例 #1
输入 #1
4输出 #1
...+...
..+.+..
.+...+.
+.....+
.+...+.
..+.+..
...+...说明/提示
数据范围
。
题目分析
解题思路
本题的解题思路如下:
问题本质:
- 在 的网格中绘制一个菱形
- 菱形的中心在第 行第 列(从 开始计数),边长为
- 菱形边上的格子用
+表示,其余用.表示
解题关键 — 判断菱形边上的点:
- 菱形上的点满足条件:与中心点的曼哈顿距离恰好等于
- 即对于第 行第 列(均从 开始计数),若 ,则该位置是菱形边上的点
- 也可以分上下两半来理解:
- 上半部分(第 到 行):第 行的
+出现在第 列和第 列 - 下半部分(第 到 行):与上半部分关于中间行对称
- 上半部分(第 到 行):第 行的
- 特殊情况:第 行和第 行只有一个
+(菱形的上下顶点)
复杂度分析:
- 时间复杂度:,需要遍历 的网格
- 空间复杂度:,只需常数个变量
示例代码
方法一、利用曼哈顿距离判断
通过判断每个位置与菱形中心的曼哈顿距离是否等于 ,来确定该位置是否为菱形边上的点。
#include <iostream>
#include <cmath>
int main() {
// 读入菱形的边长
int n;
std::cin >> n;
// 网格大小为 (2n-1) x (2n-1)
int size = 2 * n - 1;
// 菱形中心位置(行列下标均为 n-1)
int center = n - 1;
// 遍历每一行
for (int i = 0; i < size; i++) {
// 遍历每一列
for (int j = 0; j < size; j++) {
// 计算当前位置到中心的曼哈顿距离
// 若距离恰好等于 n-1,则该位置是菱形边上的点
if (std::abs(i - center) + std::abs(j - center) == n - 1) {
std::cout << "+";
} else {
std::cout << ".";
}
}
// 每行结束后换行
std::cout << std::endl;
}
return 0;
}方法二、分别计算每行的 + 位置
根据每一行到中心行的距离,直接计算 + 出现的列号,逐字符输出。
#include <iostream>
int main() {
// 读入菱形的边长
int n;
std::cin >> n;
// 网格大小为 (2n-1) x (2n-1)
int size = 2 * n - 1;
// 遍历每一行
for (int i = 0; i < size; i++) {
// 计算当前行到中心行的距离
int dist;
if (i < n) {
dist = n - 1 - i;
} else {
dist = i - (n - 1);
}
// 第 i 行的 '+' 出现在第 dist 列和第 size - 1 - dist 列
for (int j = 0; j < size; j++) {
if (j == dist || j == size - 1 - dist) {
std::cout << "+";
} else {
std::cout << ".";
}
}
// 每行结束后换行
std::cout << std::endl;
}
return 0;
}本文由coderli.com原创,按照CC BY-NC-SA 4.0 进行授权
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
“luogu-”系列题目可在 洛谷题库 在线评测。
“bcqm-”系列题目可在 编程启蒙题库 在线评测。
GESP/CSP认证交流QQ群: 688906745
GESP/CSP 认证学习微信公众号

最后更新于