php打印n乘n沙漏形状图形,打印沙漏-算法

打印沙漏

题目

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

*****

***

*

***

*****

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

输入例子

19 //多少个符号 *

输出例子

//打印出一个沙漏

*****

***

*

***

*****

2 //剩余没有用掉的符号数量

解题思路

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

(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)

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

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

(1,1)(1,2)

(2,2)

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

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

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

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

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

代码

下面是 我用 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值