Mario
要解决的问题
在任天堂 Super Mario Bros. 第 1-1 关的末尾附近,Mario 必须攀爬一个右对齐的砖块金字塔,如下图所示。

在名为 mario-less 的文件夹中的 mario.c 文件中,用 C 语言实现一个程序来重建那个金字塔,使用井号(#)表示砖块,如下图所示:
#
##
###
####
#####
######
#######
########
但要提示用户输入一个 int 类型的金字塔实际高度,这样程序也能输出如下较矮的金字塔:
#
##
###
如果用户输入的值不大于 0 或根本不是 int 类型,则根据需要反复提示用户。
提示
- 记住你可以通过
int从用户那里获取get_int, 该函数声明在cs50.h. - 记住你可以打印一个
stringwithprintf, 该函数声明在stdio.h.
演示
建议
先写一些确定能编译的代码
即使这个程序暂时什么也不做,它至少应该能用 make 编译!
#include <cs50.h>
#include <stdio.h>
int main(void)
{
}
在继续写更多代码前,先写一些伪代码
如果你还不确定如何解决问题本身,可以先把它拆成几个更小、你大概能先解决的问题。例如,这个问题其实就是两个问题:
- 提示用户输入金字塔高度
- 打印对应高度的金字塔
因此,先把伪代码写成注释,提醒自己要完成这些步骤:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt the user 的 pyramid's height
// Print a pyramid of that height
}
把伪代码转换成代码
首先,思考如何提示用户输入金字塔高度。回忆一下,当你希望某件事至少执行一次,并且可能反复执行时,do while 循环会很有帮助,如下所示:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
}
其次,思考如何从上到下打印该高度的金字塔。注意第一行应有一块砖,第二行应有两块砖,依此类推。你很可能需要一个循环,如下所示;即使暂时还不确定循环里该写什么,也可以先添加一些伪代码注释:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
for (int i = 0; i < n; i++)
{
// Print row of bricks
}
}
如何打印那一行砖块呢?如果有一个名为 print_row 的函数能完成这件事,不是很好吗?让我们假设有这样一个函数:
#include <cs50.h>
#include <stdio.h>
void print_row(int bricks);
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
for (int i = 0; i < n; i++)
{
// Print row of bricks
}
}
void print_row(int bricks)
{
// Print row of bricks
}
然后我们就可以从 main 中调用该函数,如下图所示:
#include <cs50.h>
#include <stdio.h>
void print_row(int bricks);
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
for (int i = 0; i < n; i++)
{
// Print row of bricks
print_row(i + 1);
}
}
void print_row(int bricks)
{
// Print row of bricks
}
但为什么是 i + 1 呢?
现在让我们来实现 print_row:
#include <cs50.h>
#include <stdio.h>
void print_row(int bricks);
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
for (int i = 0; i < n; i++)
{
// Print row of bricks
print_row(i + 1);
}
}
void print_row(int bricks)
{
for (int i = 0; i < bricks; i++)
{
printf("#");
}
printf("\n");
}
但为什么末尾要有 \n 呢?
不幸的是,这段代码打印的是左对齐的金字塔,而你需要的是右对齐的!或许我们应该在一些砖块前打印一些空格来将它们右移?让我们按如下方式修改 print_row,使其能同时打印空格和砖块:
#include <cs50.h>
#include <stdio.h>
void print_row(int spaces, int bricks);
int main(void)
{
// Prompt the user 的 pyramid's height
int n;
do
{
n = get_int("Height: ");
}
while (n < 1);
// Print a pyramid of that height
for (int i = 0; i < n; i++)
{
// Print row of bricks
}
}
void print_row(int spaces, int bricks)
{
// Print spaces
// Print bricks
}
现在 main 和 print_row 中都还留有一些伪代码,接下来就交给你完成了!
也可以思考一下,是否能把 main 中的一部分代码提取到一个 get_height 函数中,让它返回你需要的 int!
讲解视频
注意,这个讲解视频要求你的程序提示用户输入金字塔高度,并且当用户输入小于 1 或大于 8 的值时重新提示。题目规格只要求在用户输入小于 1 的值时重新提示。
如何测试
你的代码在以下输入情况下是否按预期工作:
-
-1或其他负数? -
0? -
1或其他正数? - 字母或单词?
- 只按 Enter 键,不输入任何内容?
正确性
check50 cs50/problems/2026/x/mario/less
代码风格
style50 mario.c
如何提交
在终端中执行以下命令提交你的作业,并按提示完成操作。
submit50 cs50/problems/2026/x/mario/less