打印沙漏
题目
顾名思义,就是要输出一个沙漏
,那么什么是沙漏呢,就是下面的样子了
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) { $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