CS50 - 卡在马里奥金字塔里

CS50 - Stuck with mario pyramid

一直在做 pset1 "Mario Pyramid" 并被关于打印的部分卡住了 "Hashes",已经尝试了不同的方法但是......什么都没有。具体来说,问题在于它定义了 "hs" 的值。 https://docs.cs50.net/problems/mario/more/mario.html这里是关于pset1的问题

#include <stdio.h>
#include <cs50.h>

int main(void)
{
    int h, s, hs, i;

    do {
        h = get_int("Height: ");
    } while (h < 0 || h > 23);

    for (i = 0; i < h; i++) {
        /* ignore 1 */
        if (i < 1) {
            printf("");
        } else {
            for (s = (h - i); s > 1; s--) {
                /* Spaces */
                printf(" ");
            }

            for (hs = 2; hs < h; hs++) {
                /* Hashes */
                printf("#");
            }

            /* Jump Line */
            printf("\n");
        }
    }
}

输出:

Height: 6
    ####
   ####
  ####
 ####
####

当它看起来像半金字塔时

在你开始编码之前,试着理解如何用铅笔解决这个问题 和纸。

特别是当你学习计算机科学课程时,更重要的是 比编程本身更了解基本原理。常常 你需要弄清楚模式。一旦你完成了,翻译它 进入程序要容易得多。

所以让我们试着弄清楚这里的模式。

这就是你想要的金字塔

   #  #
  ##  ##
 ###  ###
####  ####

你首先观察到的是什么?我们只需要看左边 金字塔的一半,因为右半部分是相同的只是镜像。

这样问题就变得简单了:

   #              |   #
  ##      -->     |  ##
 ###              | ###
####              |####

我添加了 | 以明确每一行的开始位置。所以对于 4 的金字塔:

  • 我们需要 4 行
  • 每行长度相同,4个字符
  • 从上到下空格数减少,哈希数增加 底部:

    • 第一行我们需要 4-1=3 个空格和 1 个散列
    • 对于第二行,我们需要 4-2=2 个空格和 2 个哈希值
    • 对于第三行,我们需要 4-3=1 个空格和 3 个哈希值
    • 对于第四行,我们需要 4-4=0 个空格和 4 个哈希值

    你开始看到这里的规律了吗?

所以在计算中我们从 0 开始计数。初学者经常犯这样的错误 从 1 开始计数。让我们从 0 开始重复这些句子:

  • 对于第 0 行,我们需要 4-1-0=3 个空格和 0+1=1 个哈希值
  • 对于第一行,我们需要 4-1-1=2 个空格和 1+1=2 个哈希值
  • 对于第二行,我们需要 4-1-2=1 个空格和 2+1=3 个哈希值
  • 对于第 3 行,我们需要 4-1-3=0 个空格和 3+1=4 个哈希值

因此 对于大小为 n 的金字塔:

  • 对于第 0 行,我们需要 n-1-0 个空格和 0+1=1 个哈希值
  • 对于第一行,我们需要 n-1-1 个空格和 1+1=2 个哈希值
  • ···
  • 对于第 n-1 行,我们需要 n-1-(n- 1) 空格和 (n-1)+1 hashes

你又看到这个规律了吗?

  • 对于第 i 行,我们需要 n - 1 - i 个空格和 i+1 哈希值。

我们有左半边的图案,右半边是一样的,只是 镜像。所以现在我们知道空格和哈希的数量,写一个循环 非常简单,你几乎只需要插入公式:

#include <stdio.h>

int main(void)
{
    int n = 10, i, j;

    for(i = 0; i < n; ++i)
    {
        // left half
        for(j = 0; j < n-1-i; ++j)
            printf(" ");
        for(j = 0; j < i + 1; ++j)
            printf("#");

        // 2 spaces in the middle
        printf("  ");

        // right half, we swapped the order
        for(j = 0; j < i + 1; ++j)
            printf("#");
        for(j = 0; j < n-1-i; ++j)
            printf(" ");

        printf("\n");
    }

    return 0;
}

请注意,右半部分颠倒了打印哈希和空格的顺序。 但是右边的尾随空格可以完全省略,所以最后一个 for 循环 可以删除:

        // this for loop before the printf("\n");
        // can be removed, not needed.
        for(j = 0; j < n-1-i; ++j)
            printf(" ");

解决此类问题时,尝试使用此方法,选择一个 铅笔和纸,然后用手解决。正在做 我们已经弄清楚了模式并将其翻译成代码是一部分 蛋糕。请注意,我们甚至看到问题可能是 "cut in half" 因为 的对称性。现在给你一个练习:打印相同的金字塔,但倒置。