所以我正在尝试从 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
开始的。因此,在开始时,i
和j
都等于0
。因此,由于n
是正整数,因此if
和else 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 == n
和j == 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 - 1
和j = i + n - 1
.
其次,在这两种情况下,我们在max(i) + k
时都有最大j
,换句话说n - 1 + n - 1
如此2 * n - 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 个。
注意:我使用.
而不是进行演示。