一、题目描述
输入一个奇数 n,输出一个由 *
构成的 n 阶实心菱形
输入格式:一个奇数 n。
输出格式:输出一个由 *
构成的 n 阶实心菱形。
输入样例:5
输出样例:
*
***
*****
***
*
二、一个特别牛的找规律大法
虽然是找规律,但他不像后面的大众解法那样需要分上下两部分来写,先看解析,再给代码!
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 思路
所谓大众解法,就是一行一行打印,找出空格和*的位置关系。
如下:
思路:若要打印第一星,首先就要先打印前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;
}
我们打印出来看看
很好,没有问题。
接下来,我们开始打印下半部分
下半部分和上半部分思路一样,关键在于找规律
代码如下:
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;
}
看看结果如何:
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;
}
四、曼哈顿距离解法
首先,我们需要知道什么是曼哈顿距离:
一个点到中心单元的距离被称为曼哈顿距离
在二维空间中 i, j 两点的曼哈顿距离可以表示为 d(i,j)=|xi−xj|+|yi−yj|(横、纵坐标差值的绝对值之和)。
什么意思呢?接下来我举一个例子
假设我要打印一个n = 5的菱形
通过观察我们可以发现:只要曼哈顿距离小于等于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;
}
这个方法和上面的大众解法比起来就简短太多了
我们运行起来看看如何
非常完美!