题目:
把给定的符号打印成沙漏的形状。
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
*****
***
*
***
*****
2
思想:
首先,确定最多能输出多少行的沙漏。上半部分的三角形每行符号个数为递减等差数列,下半部分的三角形每行符号个数为递增等差数列,上下共用顶尖那一行。等差数列a1=1,d=2,总符号数=(ma1+m(m-1)/2*d)*2-a1,化简后为2m2-1<=n(m为单个三角形的行数,n为沙漏符号数)。某一行应该打印的个数为a1+(mi-1)d,则第一行和最后一行应该打印的个数为2m-1个,为了中间对称,其他行应该在输出符号之前输出m-mi个空格。注意:符号后面不输出空格,仅在前面输出。
样例解析:
//2m^2-1<=19 m=3
01234//数组下标
*****//第3行 符号数=2*3-1=5个 空格数=3-3=0
*** //第2行 符号数=2*2-1=3个 空格数=3-2=1
* //第1行 符号数=2*1-1=1个 空格数=3-1=2
*** //第2行 符号数=2*2-1=3个 空格数=3-2=1
*****//第3行 符号数=2*3-1=5个 空格数=3-3=0
AC代码:
#include<iostream>
using namespace std;
int main(){
int n;
char p;
cin>>n>>p;
int m=1;
while(2*m*m-1<=n){
m++;
}
m--;
for(int i=m;i>0;i--){//上三角打印
for(int j=0;j<i+m-1;j++){
if(j<m-i) printf(" ");
else printf("%c",p);
}
printf("\n");
}
for(int i=2;i<=m;i++){//下三角打印,共用的一行不重复打印
for(int j=0;j<i+m-1;j++){
if(j<m-i) printf(" ");
else printf("%c",p);
}
printf("\n");
}
printf("%d",n-2*m*m+1);
return 0;
}