算法入门经典 习题 2-3

题目

输入正整数 n≤20,输出一个 n 层的倒三角形。

例如,n=5 时输出如下:

1
2
3
4
5
#########
#######
#####
###
#

解答

我们来分析一下:

行号 空格数 符号数 输出内容
0 0 9 #########
1 1 7 #######
2 2 5 #####
3 3 3 ###
4 4 1 #

初版(有 bug)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;

int triangle(int a)
{
//a:层数
a = a * 2 - 1;
for (int i = 0; i <= a; i = i + 2)
{
//i:每行个数
int b = 0;

//添加空格
int j = 1;
while(j <= i)
{
cout << " ";
j++;
}

while(b <= i)
{
//b:每行输出次数
cout << "#";
b++;
}
cout <<endl;
}
return 0;
}

int main()
{
int n;
cin >> n;
triangle(n);
}

输入:

1
5

输出:

1
2
3
4
5
#
###
#####
#######
#########

可以看出,这个程序的空格输出无误,

写完了才发现,题目里要求的是倒三角型,而这个程序实现的是正三角形,无奈,推翻重做。

并且,经过后续 debug 发现,第 k 行需要输出 2*(n – k) – 1 个 #,才是倒三角型。

修改后(不够简洁)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;

int triangle(int a)
{
//a:层数
a = a * 2 - 1;
for (int i = 0; i <= a; i = i + 2)
{
//i:每行个数
int b = 0;

//添加空格
int j = 1;
while(j <= i)
{
cout << " ";
j++;
}

while(b <= 2*(a - i) - 2)
{
//b:每行输出次数
cout << "#";
b++;
}
cout <<endl;
}
return 0;
}

int main()
{
int n;
cin >> n;
triangle(n);
}

输入:

1
5

输出:

1
2
3
4
5
##################
##############
##########
######
##

还是和原题目不符。

我觉得,问题应该出在这一行:

1
2
//a:层数
a = a * 2 - 1;

这一行是忘记删掉的,删掉后可以正常输出了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;

int triangle(int a)
{
//a:总行数
int t = 0;//当前操作的行号
for (int i = 0; i <= a; i = i + 1)
{
//i:每行个数
int b = 0;

//添加空格
int j = 1;
while(j <= i)
{
cout << " ";
j++;
}

while(b <= 2*(a - i) - 2)
{
//b:每行输出次数
cout << "#";
b++;
}
cout <<endl;
}
return 0;
}

int main()
{
int n;
cin >> n;
triangle(n);
}

输入:

1
5

输出:

1
2
3
4
5
6
#########
#######
#####
###
#

细心的读者可能会发现,输出多了空行!

在算法竞赛时,因为这一行空行就可能被判为错误答案!

修正(while 循环最终版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
using namespace std;

int triangle(int a)
{
for (int i = 0; i < a; i++) //改正:i <= a ==》 i < a
{
int b = 0;
int j = 1;
while(j <= i)
{
cout << " ";
j++;
}

while(b++ < 2 * (a - i) - 1) //改正:2 * (a - i) - 2 ==》 2 * (a - i) - 1
{
cout << "#";
}
cout <<endl;
}
return 0;
}

int main()
{
int n;
cin >> n;
triangle(n);
}

自此,输入输出没有问题。

核心算法

第 k 行的 # 数量为:

2*(n – k) – 1

可以明显感受到,难度陡然上升,希望对程序的理解更上一层楼吧!

祝各位读者早日成为神牛牪犇!