CS50 - 卡马里奥金字塔

时间:2018-01-22 21:50:48

标签: c cs50

一直在做pset1"马里奥金字塔"并且卡在关于打印的部分" 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
    ####
   ####
  ####
 ####
####

当它看起来像半金字塔时

1 个答案:

答案 0 :(得分:2)

在开始编码之前,请尝试了解如何使用铅笔解决此问题 和纸。

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

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

这是你想要的金字塔

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

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

所以问题变得容易了:

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

我添加|以清楚显示每行开始的位置。所以对于金字塔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个哈希
  • 对于第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哈希

你再次看到这种模式吗?

  • 对于 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(" ");

解决这类问题时,请尝试使用此方法,选择一个 铅笔和纸,并用手解决。干 我们已经找到了模式并将其转换为代码是一块 蛋糕。请注意,我们甚至看到问题可能会“切成两半”,因为 对称性。现在为你练习:打印相同的金字塔,但颠倒过来。