文章目录
一【题目难度】
- 乙级
二【题目编号】
- 1027 打印沙漏 (20 分)
三【题目描述】
- 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
- 所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
- 给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
四【题目示例】
-
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。 -
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。 -
输入样例:
19 * -
输出样例:
*****
***
*
***
*****
2
五【解题思路】
- 这个题我认为是有难度的,主要是不好确定最终多少个符号需要被打印,但是我们可以注意到沙漏是一个倒三角和一个正三角的组合,其中三角尖是共用的,所以我们可以先打印上面的倒三角,再打印下面的正三角,所以我们需要获取以下三个数据:
①:三角形的底边拥有的非空格字符数
②:每行非空格字符前面需要输出的空格数
③:还剩下多少非空格字符没有使用 - 首先确定三角形的底边拥有的字符数:设这个数为 x x x,于是一个三角形所有字符和为 1 + 3 + 5 + … … x = ( 1 + x ) 2 4 1+3+5+……x=\frac{(1+x)^2}{4} 1+3+5+……x=4(1+x)2个,因此一共需要 ( 1 + x ) 2 2 − 1 \frac{(1+x)^2}{2}-1 2(1+x)2−1个非空格字符,因为题目要求要使用最多的非空格字符,且使用的总非空格字符数不得超过输入的数字 n n n,因此解不等式 ( 1 + x ) 2 2 − 1 ≤ n \frac{(1+x)^2}{2}-1 \leq n 2(1+x)2−1≤n,可解得 x ≤ 2 ( 1 + n ) − 1 x \leq \sqrt{2(1+n)}-1 x≤2(1+n)−1,又因为 x x x为整数,所以 x = ⌊ 2 ( 1 + n ) ⌋ − 1 x=\lfloor \sqrt{2(1+n)} \rfloor - 1 x=⌊2(1+n)⌋−1,其中 ⌊ x ⌋ \lfloor x\rfloor ⌊x⌋表示对 x x x向下取整,又因为要求 x x x为奇数,所以若得到 x x x为偶数需要再 − 1 -1 −1
- 然后确定每行非空格字符前面需要输出的空格数:设某行需要输出 i i i个非空格字符,则它的左侧需要输出的空格数为 x − i 2 \frac{x-i}{2} 2x−i,其中 x x x是三角形的底边拥有的非空格字符数,右边就不用输出了,只需要输出左边就可以得到结果
- 最后确定还剩下多少非空格字符没有使用:因为再①中我们已经得到了总共输出的非空格字符数,所以多余的数即为 n − ( ( 1 + x ) 2 2 − 1 ) n-(\frac{(1+x)^2}{2}-1) n−(2(1+x)2−1)
- 还有两个需要注意的小点如下:
①: s q r t sqrt sqrt函数的参数必须是浮点数,所以需要把里面的数字写成小数形式
②:向下取整可以直接使用 i n t int int强制类型转换,也可以使用 m a t h . h math.h math.h头文件下的 f l o o r floor floor函数 - 得到了所有需要的数据就可以直接输出了,输出没有什么难度,只需要在 f o r for for循环里面逐行打印空格和非空格字符,注意别忘了打印完一行需要换行,最后还需要输出剩下多少非空格字符没有使用
六【最终得分】
- 20分
七【代码实现】
#include <stdio.h>
#include <math.h>
int main()
{
int n;
char key;
scanf("%d %c",&n,&key);
int bottom = (int)sqrt(2.0 * (n + 1)) - 1;
if(bottom % 2 == 0)
{
bottom--;
}
int used = (bottom + 1) * (bottom + 1) / 2 - 1;
for(int i = bottom;i>=1;i-=2)
{
for(int j = 0;j<(bottom - i) / 2;j++)
{
printf(" ");
}
for(int j = 0;j<i;j++)
{
printf("%c",key);
}
printf("\n");
}
for(int i = 3;i<=bottom;i+=2)
{
for(int j = 0;j<(bottom - i) / 2;j++)
{
printf(" ");
}
for(int j = 0;j<i;j++)
{
printf("%c",key);
}
printf("\n");
}
printf("%d",n-used);
return 0;
}