本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
*****
***
*
***
*****
2
分析:
根据题干我们就可以找到这个沙漏的特点,即每行的个数成等差数列。为了方便研究我们把沙漏一分为二,一个是上面的倒三角形,一个是下面的正三角形。首先我们要解决有n个符号我们最多用几个符号组成这个图形。我们先设一个倒三角型有a行,显然倒三角型符号个数就是等差数列求和,记为s,那么整个图形所用符号数就为2s-1,即2a的平方-1.那么我们就可以列一个方程,2a的平方 - 1 = n,反解出a = 根号下【(n + 1)/2】。要用到根号运算我们就调用函数 sqrt()(编程中我们遇到需要但不会的算法可以上网搜一下有没有相关函数,稍微看一下我们就可以照着应用),头文件为#include<math.h>。我们再用int型来存储就能得到一个整数,而这个整数就是这个倒三角形的的行数,再用总的减去我们用去的就是剩下的。接下来就很简单了,显然这种打印就是用嵌套的for循环,类比二维数组,只不过这里的具体循环内容需要我们找规律,就是简单的数学问题。这个规律也很好找,大家自己画一个特殊的图像,自己找一会儿就可以找出来。因为每个人找规律的方式不一样,所以具体的循环也不一样,但大体思路都是一样的,即外层循环行数,内层有两个并列循环,一层循环空格,一层循环指定符号,然后分别把上面和下面的三角形打印出来。
#include <stdio.h>
#include<math.h>
int main()
{
int i = 0, j = 0, n = 0,a = 0, res = 0;
char ar;
scanf("%d %c", &a, &ar);//输入给定字符数和字符
n = sqrt((a + 1) / 2);//计算上边完整倒三角形的行数
res = a - 2 * n * n + 1;//计算剩下多少字符没用
for (i = 1; i <= n; i++)//打印上边的倒三角形
{
for (j = 1; j < i; j++)//两个循环,分打印空格和打印字符
{
printf(" ");
}
for (; j <= 2 * n - i; j++)
{
printf("%c", ar);
}
printf("\n");
}
for (i = 2; i < n + 1; i++)//打印下边的少最上面一个符号的正三角形
{
for (j = 1; j <= n - i; j++)//两个循环,分打印空格和打印字符
{
printf(" ");
}
for (; j <= n + i - 1; j++)
{
printf("%c", ar);
}
printf("\n");
}
printf("%d\n", res);//打印剩余符号数
return 0;
}
当然我们也可以创建数组来进行打印,只不过稍微麻烦一点。这里我简单说一下思路,有兴趣的朋友可以自己敲一下。因为这里图形在变,所以我们要创建一个二维动态数组,创建好后依然用嵌套循环来打印。这个思路与上面大同小异,只不过用了动态数组。
简单评价这道题,比较简单,就是数学能力的考察,打印部分也是套路,就是类比打印二维数组的打印。