C++实现打印沙漏 详解(等差数列求和)

L1-002 打印沙漏

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *

输出样例:

*****
 ***
  *
 ***
*****

解析

  主要思路就是求出沙漏最中心点的高度,这样才方便接下来用for循环打印图像。

  首先设沙漏的最中心为第h行。

  接下来求上半部分沙漏所用的符号数,目的是求出整个沙漏所需的符号数。根据等差数列求和公式:
S n = n ( a 1 + a n ) 2 S_n=\frac{n(a_1+a_n)}{2} Sn=2n(a1+an)
a n = a 1 + ( n − 1 ) d a_n=a_1+(n-1)d an=a1+(n1)d
  于是求上半部分沙漏所用符号数相当于,求一个首项为1公差为2,一共h项,且最后一项为 a n a_n an的等差数列。于是 S 上 = h ( 1 + 1 + ( h − 1 ) ∗ 2 ) 2 = h 2 S_上=\frac{h(1+1+(h-1)*2)}{2}=h^2 S=2h(1+1+(h1)2)=h2
根据对称性,整个沙漏所用的符号数就是上半部分所用符号*2-多的中心一个符号 ,故 S 总 ,故S_总 ,故S
S 总 = S 上 ∗ 2 − 1 = 2 h 2 − 1 S_总=S_上*2-1=2h^2-1 S=S21=2h21
由题目输入的符号数为n,于是我们据此可以求出沙漏的高度h的表达式:
n = 2 h 2 − 1 n=2h^2-1 n=2h21
h = n + 1 2 h=\sqrt{\frac{n+1}{2}} h=2n+1

这样有了 S 总 S_总 S h h h的表示式后,就可以开始写代码了!ヽ(*^ー^)人(^ー^*)ノ

代码

#include<bits/stdc++.h> 
using namespace std; 
int n,h; //字符数和高度
char x;   //输入的符号

int main() 
{
    cin>>n>>x; 
    h=sqrt((n+1)/2); /* 高度 */
    for(int i=h;i>=1;i--) // 第一个for循环,从h到1递减,用来打印沙漏的上半部分
    {
        for(int j=1;j<=h-i;j++)cout<<' '; // 第一个内部循环,用来打印空格
        for(int j=1;j<=2*i-1;j++)cout<<x; // 第二个内部循环,用来打印字符x
        cout<<endl; // 换行
    }
    for(int i=2;i<=h;i++) // 第二个for循环,从2到h递增,用来打印沙漏的下半部分
    {
        for(int j=1;j<=h-i;j++)cout<<' '; // 第一个内部循环,用来打印空格
        for(int j=1;j<=2*i-1;j++)cout<<x; // 第二个内部循环,用来打印字符x
        cout<<endl;
    }
    cout<<n-(2*h*h-1)<<endl; // 提供的字符数-用到的字符数
    return 0;
}

附送一张壁纸  (^  ^)/~
在这里插入图片描述

  • 13
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值