本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
***** *** * *** *****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
题目分析:
1、首先找到给定目标数字后能达到的最大沙漏(计算行数,即row)
2、 根据row两个大的for循环,打印沙漏的上下形状,每个for循环中每次分开打印空格和符号
设计知识点:使用二级等差数列简便计算出不同i对应的符号总数,再据此计算row:
二级等差数列,称差等差数列,就是数列的后项减前项,组成的新数列是等差数列。比如3,7,12,18 ,25就是二级等差数列
7-3=4 12-7=5 18-12=6 25-18=7二级等差数列
利用差分公式可以给出二级等差数列的通项公式:
an=a1+(a2-a1)(n-1)+(a3-2a2+a1)(n-1)(n-2)/2
其中a1-2a2+a3=(a3-a2)-(a2-a1)也可称为二级等差数列的公差.
本题中二级等差数列为:1、7、17、31
公式计算:1+(7-1)*(n-1)+(17-2*7+1)*(n-2)*(n-1)/2 = 2n^2-1
#include<bits/stdc++.h>
#define MAX 100010
using namespace std;
main(int argc, char *argv[])
{
int n,sum=0,row;
char c;
cin>>n>>c;
for(int i=0;i<n;i++)
{
sum=2*(i+1)*(i+1)-1;//因为每一行的*为2i+1个(i从0开始) 而计算总数时从第一项开始 即下标从1开始 所以需要额外+1
if(sum>n)
{
row=i-1;
break;
}
}
for(int i=row;i>=1;i--)//上半个沙漏
{
for(int j=row-i;j>=1;j--)
cout<<" ";
for(int j=2*i+1;j>=1;j--)
cout<<c;
cout<<endl;
}
for(int i=0;i<row;i++) cout<<" ";//额外打印正中那一行
cout<<c<<endl;
for(int i=1;i<=row;i++)//下半个沙漏
{
for(int j=row-i;j>=1;j--)
cout<<" ";
for(int j=2*i+1;j>=1;j--)
cout<<c;
cout<<endl;
}
// cout<<row<<endl;
cout<<n-2*(row+1)*(row+1)+1;//道理同最上一条注释
return 0;
}