1027. 打印沙漏(20)
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
***** *** * *** *****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:19 *输出样例:
***** *** * *** ***** 2
思路:此题的关键在于如何计算出一个完整沙漏的行数,在此采用逐行相加和输入数目比较的方法
一、起始变量:
1.N 输入的符号数
2.sign输入的符号
3.sum 所要用的符号数
4.row沙漏的行数
二、思路
1.逐行相加计算使用的符号数量,直到超过N。
2.在第一步的基础上剪掉多出来的符号数得到使用的符号数sum
3.计算出row
4.输出按row及对应的规律输出空格和制定符号
三、代码
#include "stdio.h"
int main()
{
int N;
char sign;
scanf("%d %c",&N ,&sign);
int sum = 0; //计算用掉的符号个数
int row;//一个完整沙漏的行数
int i,j;
for(i = 1; sum <= N; i++)
{
//寻找最大的行数
if(i == 1)
{
sum = 1;//当只有一行时,只使用一个字符
}
else
sum += 2 * (i * 2 - 1);//除第一行之外,每多一行,就多出2*i-1个字符,又因为要画出两个沙漏,故再乘以2.
}
sum = sum - 2 * ((i - 1) * 2 - 1);//在退出for循环时,sum多加了一行,故在sum中减掉多计算的字符
row = i - 2;//因为在退出for循环时i比多出来的行数还大1,所以减2
/*
比如输入
19 *
输出符合题意的沙漏要用掉17个
*****
***
*
***
*****
在i = 3时,sum = 17,之后i = i + 1 = 4;
i = 4时,sum = 31,之后i = i + 1 = 5;
退出for循环时i = 5, sum = 31;
sum = 31 - 2 * ((5 - 1) * 2 - 1 ) = 17;
行数row = i - 2 = 5;
*/
int antiCount = row;//用来辅助计算每行的空格数目
for(i = row; i >= 1 ; i--,row--)//输出沙漏的上半部分
{
for(j = 0; j < antiCount - row; j++)
{
//先输出空格
printf(" ");
}
for(j = 0; j < 2 * row - 1; j++)
{
//再输出符号
printf("%c",sign);
//最后一个符号之后输出换行
if(j == 2 * row - 2)
printf("\n");
}
}
row = 2;//下方三角开始从第二行打印
for(i = 2; i <= antiCount; i++,row++)
{
//此时antiCount为最大行数,用作退出循环的条件
for(j = 0; j < antiCount - row; j++)
{
printf(" ");
}
for(j = 0; j < 2 * row - 1; j++)
{
printf("%c",sign);
if(j == 2 * row - 2)
printf("\n");
}
}
printf("%d", N - sum);
return 0;
}