dream

一个菜鸟程序员的成长历程

0%

打印沙漏

打印沙漏

题目

顾名思义,就是要输出一个沙漏,那么什么是沙漏呢,就是下面的样子了

1
2
3
4
5
*****
***
*
***
*****

也就是要给我们n个*,这个沙漏每一行的 符号 数量都是奇数,因此是有规律的。

输入例子

19 //多少个符号 *

输出例子

1
2
3
4
5
6
7
//打印出一个沙漏
*****
***
*
***
*****
2 //剩余没有用掉的符号数量

解题思路

这个解题思路是我在网上看到的,他把这个沙漏 具像化,*号用坐标来显示,那么上面的例子就是

1
2
3
4
5
(0,0)(0,1)(0,2)(0,3)(0,4)
(1,1)(1,2)(1,3)
(2,2)
(3,1)(3,2)(3,3)
(4,0)(4,1)(4,2)(4,3)(4,4)

这样的话,继续观察一下,发现他可以上下对折,左右对折变成下面这样

1
2
3
(0,0)(0,1)(0,2)
(1,1)(1,2)
(2,2)

发现了什么,列 >= 行,然后接下来左右对称,上下对称

1
当 行坐标 > 行数 / 2 也就是过半的时候, 这时的行坐标 = 总行数 - 当前行数 - 1,比如下一行 行坐标 3 = 5 - 3 -1 = 1 所以 行坐标 3 的行和行坐标 1 的行对称。

列也是一样 因为列数 = 行数 所以

1
当 列坐标 > 行数 / 2 也就是过半的时候, 这时的列坐标 = 总行数 - 当前列数 - 1,比如下一列 列坐标 3 = 5 - 3 - 1 = 1 所以列坐标 3 的列和列坐标 1 的列对称。

当然了,中间那一行(列)没有对称

代码

下面是 我用 php 实现的代码,任何语言都大同小异。

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
function test($count, $symbol)
{
$maxRow = 1; //最大行 即 最小行
$maxCount = 1; //最大个数 即 最小个数
//先判断 数量 如果是小于 最小个数 那么输出 数量
if ($count < $maxCount) {
printf($count);
} else {
//循环 算出 最大行数 统计最大个数 后面用来算剩余个数
while (true) {
//可以输出
//下一行的数量 = 之前的数量 + 下一行所需的数量((行数 + 2) 是下一行的数量,但是沙漏需要上下两行,所以 * 2)
$nextCount = ($maxRow + 2) * 2 + $maxCount;
//判断不够了 结束
if ($count < $nextCount) {
break;
} elseif ($count == $nextCount) {
//刚好够 数量增加 行增加
$maxRow += 2;
$maxCount = $nextCount;
break;
} else {
//完全够 数量增加 行增加 然后继续循环
$maxRow += 2;
$maxCount = $nextCount;
}

}
//开始输出
for ($i = 0; $i < $maxRow; $i++) {
//循环所有行
$row = $i; //当前行
//判断 当前行 到一半了,那么把行数倒过来,让它向上跑
if ($i > $maxRow / 2) {
$row = $maxRow - $row - 1;
}
for ($j = 0; $j < $maxRow; $j++) {
//循环所有列
$col = $j;
//列和行一样 做个判断
if ($col > $maxRow / 2) {
$col = $maxRow - $col - 1;
}
//如果 当前列 < 当前行
if ($col < $row) {
//如果 到了 最后 就要换行 在 前面 则输出 空格
if ($j > $maxRow / 2) {
printf("\n");
break;
} else {
printf(" ");
}

} else {
//列 > 行 直接输出 符号
printf($symbol);
}
//输出完 最后一个符号后 换行 当列 = 最后一行的时候
if ($j == $maxRow - 1) {
printf("\n");
}
}
}
//输出 剩余的 符号数量
printf($count - $maxCount);
}

}

参考资料

我只是略作更改,最小使用1个*,和一些变量使用上的微调 下面原文c语言的链接

https://blog.csdn.net/hcy2319964421/article/details/53103641