c语言:时之沙漏

 

*****
 ***
  *
 ***
*****

 在PTA中有这样一道题,要求输入一个数和一个字符,输出由该字符组成的沙漏,并在最后一行计算出多余的字符的个数。

分析:

本题为金字塔的进阶版,大体思路可以仿照金字塔来写出代码,但要注意输入为总字符数,需要转化一下思路。

我们首先观察该漏斗的规律,可以发现:

(1)最中间一行为一个字符,分别向上下两方向以每行 +2 的规律增加。

(2)第一行没有空格,从第二行开始每行增加一个空格直到最中间一行为止。

(3)沙漏可以分解为两个图形,分别是一个完整的倒金字塔,和一个缺一行的正金字塔。

(4)若沙漏共有 n 个字符,则沙漏的上半部分的行数 i 可根据不等式方程 2 * i * i - 1 <= n 解出。

(5)最终的剩余的数目也可以用 n -( i * i * 2 - 1)解出。

思路

第一步

首先将我们不熟悉的输入的总字符数计算为我们所熟悉的一个完整的倒金字塔的行数。

第二部

​
while ()//控制金字塔中的行数
{
	for ()//控制金字塔中每一行的空格数
	{

	}
	for ()//控制金字塔中每一行的字符数
	{

	}
	printf("\n");//换行

}

​


一个循环内嵌两个循环的方式输出第一个金字塔。

第三部

输出下半部分缺一行的金字塔

在计算金字塔的行数时应该减小 1

第四部

计算出最终剩余的字符。

原代码如下

int main()
{
	int s, i = 1, n, x = 0, y = 0, rest;//n表示总输入数,i表示一半的行数
	char o;
	scanf("%d %c", &n, &o);
	while (2 * i * i - 1 <= n)
	{
		i++;
	}
	i--;
	y = 2 * i - 1;
	rest = n - 2 * i * i + 1;
	//printf("%d", i);//此处是为了方便得出所求的i的值
	while (i > 0)
	{
		for (int j = 0; j < x; j++) //x用于控制空格数,始终++或者--
		{
			printf(" ");
		}
		for (int j = 0; j < y; j++) //y用于控制字符数,始终+=2或者-=2
		{
			printf("%c", o);
		}
		printf("\n");
		x++;
		y -= 2;
		i--;
	}
	//printf("%d %d %d", i, x, y); i=0 x=3 y=-1
	x--;
	y += 2;
	while (x > 0)
	{
		x--;
		y += 2;
		for (int j = 0; j < x; j++)//此处的x,y也不要随便换,晕,容易错。
		{
			printf(" ");
		}
		for (int j = 0; j < y; j++)
		{
			printf("%c", o);
		}
		printf("\n");
	}
	printf("%d", rest);
	return 0;
}

代码中值得注意是:

分别控制输出每行中的空格数和字符数时,我分别用了两个字母x,y来控制,而不是直接将所计算出的规律的数学公式带入其中,这样写的好处是:思路更加清晰,而且不容易错!!

总结:

当我们碰到和金字塔类似的题目时,大多都可以用

while()//控制金字塔中的行数
{
	for ()//控制金字塔中每一行的空格数
	{

	}
	for ()//控制金字塔中每一行的字符数
	{

	}
	printf("\n");//换行

}

模板为基础,然后用找出的规律,让金字塔倒置等等,再加上简单的数学公式而求解出正确的答案。

(注:本文为原创作品,若无意侵权,请联系我。)

欢迎点赞 👍 关注收藏 ⭐留言 📝  

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值