c语言 - 为什么我的金字塔中间没有空间?



所以我正在尝试从 cs50 开始解决 https://cs50.harvard.edu/x/2021/psets/1/mario/more/这个问题集。

我花了太长时间才走到这一步(在 youtube 的帮助下 5-6 小时)。

#include <cs50.h>
#include <stdio.h>
int get_positive_int(void);
int main(void)
{
int n = get_positive_int();
// Run a below loop until i is greater than n
for(int i = 0; i < n; i++)
{
// Run if statement on the same row until j is greater than n*2 + i+1
for(int j=0; j < n*2 + i+1; j++)
{
// Create a blank space in exact center of the pyramid
if(j + i - n == 0 || j + i - n == 1)
printf(" ");
//If the value of n-1 is less than the combined value of j and i, or 
//if the value of i and n minus j is less than or equal to zero print #
else if ( j + i > n - 1 || i + n - j <= 0)
printf("#");
else 
//otherwise print " "
printf(" ");
}
printf("n");
}
}

为什么下面的不在我的金字塔中心创建一个双"?

if(j + i - n == 0 || j + i - n == 1)
printf(" ");

为什么当我为 n 选择值 1 时,程序不打印任何内容?

这种特定类型的思维/数学叫什么?我很难掌握它,我不确定如何在网上找到信息,因为我不知道它叫什么。

我的输出如下。 当 N = 8 时

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

我想要的输出是。 当 N = 8 时

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

当我输入值 1 时,我得到。


当我输入 1 时,我想要的是,

#  #

我想知道为了自己解决问题,我具体做错了什么,而不是如果可能的话直接回答。

首先,观察你的两个for循环都是从0开始的。因此,在开始时,ij都等于0。因此,由于n是正整数,因此ifelse if子句都将被计算为false,并且仅执行最终的else,即printf(" ");

现在看看你的金字塔。您的"金字塔"用n行和2*n + 2列填充空间。第一个循环for (i = 0; i < n; i++)是针对行的,这是正确的,因为有n行。但是,您的第二个for循环有问题。应该是for (int j=0; j < n*2 + 2; j++).

现在,当我们查看第 i 行时,我们看到(记住行从0开始,因为我们从0开始计算i),您要打印 n-1-i 空格,后跟 i+1#个字符,后跟 2 个空格,后跟 i+1#个字符,最后是 n-1-i 空格。所以"空格"是当j < n-1-i(记住j也是从0开始),当j == nj == n+1时,当j > n+2+i

这可以使用if-else编写如下:

if ( j < (n-1-i) || j == n || j == n+1 || j > n+2+i) printf(" ");
else printf("#");

因此,最终代码将如下所示:

#include <cs50.h>
#include <stdio.h>
int get_positive_int(void);
int main(void)
{
int n = get_positive_int();

for(int i = 0; i < n; i++)
{
for(int j=0; j < n*2 + 2; j++)
{
if ( j < (n-1-i) || j == n || j == n+1 || j > n+2+i) printf(" ");
else printf("#");
}
printf("n");
}
}

从数学上考虑这个问题。你有-1的斜率,所以我们有j = -i + k。我们的公式变得k = i + j.如果我们有n = 5

i j k
0 4 4
1 3 4
2 2 4
3 1 4
5 0 4

n = 6

i j k
0 5 5
1 4 5
2 3 5
3 2 5
4 1 5
5 0 5

所以k = n - 1

那是上半场,下半场更容易,j = i + k,所以k = j - i.它是正斜率移动k。所以对于n=5

i j k
0 4 4
1 5 4
2 6 4
3 7 4
5 8 4

n = 6

i j k
0 5 5
1 6 5
2 7 5
3 8 5
4 9 5
5 10 5

看看我们在两种情况下都有匹配k = n - 1.所以我们的公式是j = -i + n - 1j = i + n - 1.

其次,在这两种情况下,我们在max(i) + k时都有最大j,换句话说n - 1 + n - 1如此2 * n - 2

所以:

  1. 我们得到了你的台词。
  2. 看近了,你会看到你的j要走多远。

这是代码:

// int get_positive_int(void);
int main(void)
{
int n = 5; //get_positive_int();
// Run a below loop until i is greater than n
for(int i = 0; i < n; i++)
{   
// Run if statement on the same row until j is greater than n*2 + i+1
for(int j = 0; j < n * 2 - 1; j++)
{                                                                                                                                                     
// Create a blank space in exact center of the pyramid
if (j == n - i - 1 || j == n + i - 1)
printf("#");
else 
//otherwise print " "
printf(".");
}   
printf("n");
}   
}

输出:

....#....
...#.#...
..#...#..
.#.....#.
#.......#

现在你可以通过查看这个来优化它,以减少内部循环执行的数量25%。我不需要超出我打印第二个#的点,这意味着超出我的第二个公式max(j) = j + 1+ 1是因为我仍然希望能够进入循环,所以我们得到最大max(j) = (n + i - 1) + 1

#include <stdio.h>
// int get_positive_int(void);
int main(void)
{
int n = 5; //get_positive_int();
// Run a below loop until i is greater than n
for(int i = 0; i < n; i++)
{
// Run if statement on the same row until j is greater than n*2 + i+1
for(int j = 0; j < n + i; j++)                                                                                                                        
{
// Create a blank space in exact center of the pyramid
if (j == n - i - 1 || j == n + i - 1)
printf("#");
else
//otherwise print " "
printf(".");
}
printf("n");
}
}

输出:

....#
...#.#
..#...#
.#.....#
#.......#

如果你注意到,通过数学思考,你可以节省很多操作。例如,在第二个for()循环中,OP 和其他答案有 1 个以上的运算,其中 1 个,if/else两者都有 2 个以上的相等语句,这个有 2 个。

注意:我使用.而不是进行演示。

最新更新