本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
*****
***
*
***
*****
2
题解:
想必很多小伙伴刚开始看到这个题目的时候觉得这题很简单,上手很容易,但是当真正思考做起来的时候,发现还是有点无从下手的。所以我现在就讲解一下这题我的思路和解法~
第一部分 分解
首先这个“沙漏”是上下对称的,我们可以先找中间以上有几层(包括中间那一层),找到之后上面的层数之后减一,就是下面的层数。
我们用总数相减法来求上面的层数:
除了第一次(也就是减去中间)是一个,其他都是减去2*i,每减一次,都需要计数。一直往下减,直到x为负数,计数停止。
比如:14 *
这里x为14,第一次x=14-1=13;count=1;
第二次x=13-2x3=7;count=2;
第三次x=7-2x5=-3<0
跳出循环,因为count为2,所以上面有两层。
由于减去第一层和减去多层少个二倍,所以将一层和多层单独来写。
由此思路,代码如下:
int Count(int x)
{
int flag = 1, count = 1, i = 3;
if (x < 7)//一层
return 1;
else//多层
{
x -= 1;//先减去中间层
while (flag)
{
x -= 2 * i;
if (x >= 0)
{
flag = 1;
count++;
}
else
flag = 0;
i += 2;
}
}
return count;
}
这里就将上面的层数count求出来了,下面的层数就是count-1;
第二部分:打印
上半面
这里找到层数后,就开始考虑打印了。
打印分为空格和*。这里我用表格来显示各部分各部分之间的联系。
由于只需要打印每一层 * 之前的空格就可以,
表格如下 :
for(j=0;j<count;j++) | 空格个数 |
---|---|
j=0 | 0 |
j=1 | 1 |
j=2 | 2 |
… | … |
j=n | n |
所以打印空格的代码如下:
for (i = 0; i < count; i++)
{
for (j = 0; j < i; j++)
printf(" ");
}
现在我们来考虑打印*的部分,还是老样子,表格如下:
for(j=0;j<count;j++) | * 的个数 |
---|---|
j=0 | 2*count-1 |
j=1 | 2*(count-1)-1 |
j=2 | 2*(count-2)-1 |
… | … |
j=n | 2*(count-j)-1 |
所以代码如下:
int k = count;
for (i = 0; i < count; i++)
{
for (j = 0; j < 2 * k - 1; j++)
{
printf("%c", c);
}
k--;
}
好的,到此,沙漏的上半部分就完成了~
下半面
老样子,咱还是先看空格部分,如下图所示
这里我们可以用数学公式,来求出第一层的空格数,下面每一层的空格则只需根据上一层的空格数-1即可。
求第一层的空格数:
第一层空格数=(用最后一层‘ * ’个数-第一层‘ * ’个数)/2
怎么求最后一层‘ * ‘个数呢,用刚刚上面的公式:2*count-1
所以打印空格代码如下:
int l=0;
l = count * 2 - 1;
l = (l - 3) / 2;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < l; j++)
printf(" ");
l -= 1;
}
好,打印完下半面空格数,我们来打印下半面的*。这里就很简单,由于第一层的*的个数是3,不变,下一层只需要在原有基础上加2。
所以打印‘ * ’代码如下:
int n = 3;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < n; j++)
{
printf("%c", c);
}
n += 2;
}
到此打印就完成了,现在就差输出剩下没用掉的符号数~
输出未用符号数
只需要在打印函数里,对每一次打印*时进行计数即可。
int Printc(int count, char c)
{
int count1 = 0;
for (i = 0; i < count; i++)
{
for (j = 0; j < 2 * k - 1; j++)
{
printf("%c", c);
count1++;
}
}
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < n; j++)
{
printf("%c", c);
count1++;
}
}
}
总代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Count(int x)
{
int flag = 1, count = 1, i = 3;
if (x < 7)
return 1;
else
{
x -= 1;
while (flag)
{
x -= 2 * i;
if (x >= 0)
{
flag = 1;
count++;
}
else
flag = 0;
i += 2;
}
}
return count;
}
int Printc(int count,char c)
{
int i = 0, j = 0, k = 0, l = 0, n = 3;
int count1 = 0;
l = count * 2 - 1;
l = (l - 3) / 2;
k = count;
for (i = 0; i < count; i++)
{
for (j = 0; j < i; j++)
printf(" ");
for (j = 0; j < 2 * k - 1; j++)
{
printf("%c", c);
count1++;
}
printf("\n");
k--;
}
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < l; j++)
printf(" ");
for (j = 0; j < n; j++)
{
printf("%c", c);
count1++;
}
printf("\n");
l -= 1;
n += 2;
}
return count1;
}
int main()
{
int x = 0, y = 0;
char c = 'a';
scanf("%d %c", &x, &c);
y = Count(x);
int F=Printc(y,c);
printf("%d\n", x-F);
return 0;
}
好啦~今天C语言分享题到此结束,咱们下期再见