天梯赛L1-002打印沙漏
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数
输入样例:
19 *
输出样例:
*****
***
*
***
*****
2
思路:
1、将沙漏一分为二且补上一个尖角,得到两个三角形。
2、将两个三角形中各行的符号数看成数列,得到两个等差数列(本文将两个数列均视为递增数列),显然该数列首项为1,公差为2.
3、
设n为单各沙漏的行数。那么一个三角形需要的符号数Sn=nn.两个则需要2Sn.而其中一个尖角是我们补上的,因此沙漏的符号数等于两个三角形符号数减1,沙漏的行数等于2n-1。到这里题目的后一小问就迎刃而解,剩下没用的字符数等于N-(2nn-1)
3、题目给定符号数,我们可以通过枚举法求出尽可能大的n。
4、输出也分成两部分
5、外围循环用i计数,i<=n为判断条件。输出n行。内层用两个循环。
一个输出空格:空格数量的规律为第i行输出i-1各空格
一个输出符号:这里又要用到等差数列的知识。数列的通项公式为an=2n-1。第一个三角形是顶点往下的,利用此层循环计数变量fuhao.第i行的符号数列等于2*(n-i+1)-1=2n-2i+1 (因水平有限,此处讲得不够清晰,请读者细细琢磨)
6、第二个三角形是第一个的翻转,这里不细讲。(其实计数外层循环的条件换了而已)
7、另外,外层循环循环一次则要输出一个回车。
本题代码如下:
#include<stdio.h>
int main()
{
int i,kong,n=0,N,fuhao;
char op;
scanf("%d ",&N); \\输入符号的数量
scanf("%c",&op); \\输入符号
while(N>=2*n*n-1) \\利用枚举法求出n,n表示含尖角的半个沙漏的行数。运用到等差数列的知识
n++;
if(2*n*n-1>N) \\消除2*n*n-1从小于N突变为大于N的情况
n--;
for(i=1;i<=n;i++) \\先输入含尖角的半个沙漏
{
for(kong=1;kong<i;kong++) \\利用循环输出所需个数的空格
printf(" ");
for(fuhao=1;fuhao<=2*n-2*i+1;fuhao++) \\利用循环输出所需个数的符号
printf("%c",op);
printf("\n"); \\行末换行
}
for(i=n-1;i>=1;i--) \\基本与上个循环相同,只是修改循环起始计数数和判断条件
{
for(kong=1;kong<i;kong++)
printf(" ");
for(fuhao=1;fuhao<=2*n-2*i+1;fuhao++)
printf("%c",op);
printf("\n");
}
printf("%d",N-2*n*n+1); lou \\输出剩余的符号数量
return 0;
}