本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
结尾无空行
输出样例:
*****
***
*
***
*****
2
解法(一):
现在只对上半部分分析
*****
***
*
观察图像可知,上半部分*的个数与行的关系为 1 1;2 3;3 5;n只是上部分行数
知道每一行需要的符号个数:可知道是等差数列{An=a1+(n-1)d} An=1+(n-1)2
知道凑齐沙漏一共需要的符号个数:等差数列求前n项和{Sn=n*a1+n(n-1)d/2或 Sn=n(a1+an)/2} Sn=+
-1=2
-1
现在可以得出沙漏用符号的总个数,可以用来求剩余符号的个数.
具体代码如下:
#include<stdio.h>
#include<math.h>
int main(){
int num=0,c,n=0,i,remainder=0,over_num=0,num_x;char f;
scanf("%d %c",&num_x,&f);
for(num=1;over_num<num_x;num++){
over_num=pow(num,2)+pow(num,2)-1;//求搭建沙漏的*个数
//上面利用over_num求出使用公式
if(num_x<over_num) {//因为上面求沙漏的个数,会出现多余符号时,num会多加一个
//所以需要减去
num-=1;
}
if(over_num<=num_x) remainder=num_x-over_num;//剩余的符号
}
//以下代码用于输出
//先输出沙漏上部分 num-1为上部分沙漏的行数
for(i=num-1;i>0;i--){
for(c=0;c<num-1-i;c++){
printf(" ");
}
for(c=2*i-1;c>0;c--){//c是利用了公式
printf("%c",f);
}
printf("\n");
}
//输出沙漏的下部分
for(i=2;i<=num-1;i++){//因为下部分开始就是2个符号,所以初值为2
for(c=num-1-i;c>0;c--){
printf(" ");
}
for(c=2*i-1;c>0;c--){
printf("%c",f);
}
printf("\n");
}
n=num-1+num-2;//行数
printf("%d",remainder);//打印出行数,剩余的个数
return 0;
}
其他方法可参考: