C语言——打印菱形

一、题目描述

输入一个奇数 n,输出一个由 * 构成的 n 阶实心菱形

输入格式:一个奇数 n。

输出格式:输出一个由 * 构成的 n 阶实心菱形。

输入样例:5
 
输出样例:
  *  
 *** 
*****
 *** 
  *  

二、一个特别牛的找规律大法

虽然是找规律,但他不像后面的大众解法那样需要分上下两部分来写,先看解析,再给代码!

154349fd20de4723986b37e100551b45.jpeg

 

int main()
{
	int n = 0;
	printf("请输入一个奇数\n");
	int a = 0;
	scanf("%d", &n);

	for (int i = 0; i < n ; i++) 
	{
		for (int j = 0; j < n ; j++) 
		{
			if (j >= n / 2  - a && j <= n / 2  + a) 
			{
				printf("*");
			}
			else 
			{
				printf(" ");
			}
		}
		if (i >= n / 2 ) 
		{
			a--;
		}
		else 
		{
			a++;
		}
		printf("\n");
	}
	return 0;
}

三、大众解法

3.1 思路

所谓大众解法,就是一行一行打印,找出空格和*的位置关系。

如下:

a3681aaee3674232a605ab323d2bdcf5.png

思路:若要打印第一星,首先就要先打印前6个空格,下面部分也是如此。所以,为了方便打印,我们可以分成上半部分和下半部分,上半部分空格个数由多变少,星个数由少变多;下半部分空格个数逐渐变多,星星个数逐渐变少。

因此假设n = 13,下半部分就是6行,和n的关系也就是n / 2,则上半部分就是 n - 下半部分。然后通过循环来遍历空格和星号就可以了。

对于上半部分的代码如下:

int main()
{
	int n = 0;
	printf("输入一个奇数\n");
	scanf("%d", &n);
	int down = n / 2; //下半部分的行数
	int up = n - down; //上半部分的行数

	//打印上半部分
	for (int i = 0; i < up; i++) //控制行
	{
		//打印空格
		//通过规律可以发现是up - 1 - i
		for (int j = 0; j < up - 1 - i; j++)
		{
			printf(" ");
		}

		//打印 *
		//因为*是奇数且递增的,所以也不难发现是2 * i + 1
		for (int j = 0; j < 2 * i + 1; j++)
		{
			printf("*");
		}
		//切记每打完一行都要换行
		printf("\n");
	}
	return 0;
}

我们打印出来看看

94e64fd7fecc49b9a78a87b7374a4e21.png

很好,没有问题。

接下来,我们开始打印下半部分

下半部分和上半部分思路一样,关键在于找规律

代码如下:

int main()
{
	int n = 0;
	printf("请输入一个奇数\n");
	scanf("%d", &n);
	int down = n / 2; //下半部分的行数
	int up = n - down; //上半部分的行数



	//打印下半部分
	for (int i = 0; i < down; i++) //控制下半部分的行
	{
		//打印空格
		//空格的个数恰好就是下半部分的行数
		for (int j = 0; j <= i; j++)
		{
			printf(" ");
		}

		//打印 *
		//这个规律也不难发现。它是奇数且递减
		for (int j = 0; j < 2 * (down - i) - 1; j++)
		{
			printf("*");
		}
		//打印完一行别忘记换行
		printf("\n");
	}

	return 0;
}

看看结果如何:

49f7868ed3ac4339aa72cdbb084ae370.png

3.2 最终代码

现在上下两部分都已经写完了,我们只需将两部分合在一起就可以写出最终代码了。

int main()
{
	int n = 0;
	printf("请输入一个奇数\n");
	scanf("%d", &n);
	int down = n / 2; //下半部分的行数
	int up = n - down; //上半部分的行数

	//打印上半部分
	for (int i = 0; i < up; i++) //控制行
	{
		//打印空格
		//通过规律可以发现是up - 1 - i
		for (int j = 0; j < up - 1 - i; j++)
		{
			printf(" ");
		}

		//打印 *
		//因为*是奇数且递增的,所以也不难发现是2 * i + 1
		for (int j = 0; j < 2 * i + 1; j++)
		{
			printf("*");
		}
		//切记每打完一行都要换行
		printf("\n");
	}

	//打印下半部分
	for (int i = 0; i < down; i++) //控制下半部分的行
	{
		//打印空格
		//空格的个数恰好就是下半部分的行数
		for (int j = 0; j <= i; j++)
		{
			printf(" ");
		}

		//打印 *
		//这个规律也不难发现。它是奇数且递减
		for (int j = 0; j < 2 * (down - i) - 1; j++)
		{
			printf("*");
		}
		//打印完一行别忘记换行
		printf("\n");
	}

	return 0;
}

dbfaa5a0387a4661808f2c8fab42521a.png

四、曼哈顿距离解法

首先,我们需要知道什么是曼哈顿距离:

一个点到中心单元的距离被称为曼哈顿距离
在二维空间中 i, j 两点的曼哈顿距离可以表示为 d(i,j)=|xi−xj|+|yi−yj|(横、纵坐标差值的绝对值之和)。

什么意思呢?接下来我举一个例子

假设我要打印一个n = 5的菱形

1949895b98714b1b926468fddb06a4b6.png

通过观察我们可以发现:只要曼哈顿距离小于等于2的就是星星,大于2的就是空格!

接下来我们就要找n和它们的关系

中心坐标的坐标是(2,2),也就是x = n / 2,y = n / 2

同样的,只要曼哈顿距离小于等于2的就是星星,也就是只要距离是小于等于n / 2的就是星星,否则就是空格

int main()
{
	int n = 0;
	printf("请输入一个奇数\n");
	scanf("%d", &n);
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			if ((abs(i - n / 2) + abs(j - n / 2)) <= n / 2)
				printf("*");
			else
				printf(" ");
		}
		printf("\n");
	}
	return 0;
}

这个方法和上面的大众解法比起来就简短太多了

我们运行起来看看如何

cd6c1b0de69045349e32319dc9c5434e.png

非常完美!

 

 

 

  • 15
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Byte Master

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值