PTA-打印沙漏

题目

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

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

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

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

输入格式

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

输出格式

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

输入样例

19 *

输出样例

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

思路

沙漏分为上下两个部分,可以看出,每行的符号数都是1、3、5、7...个并且上下对称,最中间一定是一个符号。看测试用例,假如总共有19个符号,用19减去最中间的1,再除以2,(19 - 1) / 2 = 9,即得到上下两半最多各有9个字符。我们只看上半部分,9 - 3 = 6,即中间上面的一行。3是这一行的字符个数,6是剩余的字符个数。再继续向上构建,6 - 5 = 1,5是这一行的字符个数,1是剩余的字符个数。接着,1 - 7 = -6 < 0,结束构建。这里我想到用一个vector容器来存储每行的字符个数。结合while循环便可以求出这个数组。

输出部分:我们需要将沙漏这个图形输出,可以将其拆分成上半部分和下半部分输出,用两个for循环。输出每行,就需要先输出空格,再输出字符。每行空格数目的计算可以用最大字符个数减去每行的字符个数,再除以2。比如测试用例,最大字符个数即为5。

剩下的符号数:需要注意的是,刚开始我们将字符总数减1再除以2,如果字符总数是偶数,就不能被整除。所以算这个剩余数目不能放在刚开始的while循环里,可以在输出的时候,一边输出,一边让总数减去输出数。

代码

#include <iostream>
#include <vector>
using namespace std;

int main(){
    int n;
    char c;
    cin >> n >> c;
    vector<int> sha;

    int pos = (n - 1) / 2;//当前符号的总数(单向)
    int poss = 1;//当前行符号的个数
    sha.push_back(poss);
    poss += 2;
    int max = 1;//符号数的最大值
    int sy = n;//剩余的符号数
    while (pos - poss >= 0){
        sha.push_back(poss);
        max = poss;
        pos -= poss;
        poss += 2;
    }

    for (int i = (int)sha.size() - 1; i >= 0; i--){
        int cnum = sha[i];//当前行符号的个数
        sy -= cnum;
        int knum = (max - sha[i]) / 2;//当前行空格的个数
        for (int j = 0; j < knum; j++){
            cout << " ";
        }
        for (int j = 0; j < cnum; j++){
            cout << c;
        }
        cout << endl;
    }//打印上半部分
    for (int i = 1; i < (int)sha.size(); i++){
        int cnum = sha[i];
        sy -= cnum;
        int knum = (max - sha[i]) / 2;
        for (int j = 0; j < knum; j++){
            cout << " ";
        }
        for (int j = 0; j < cnum; j++){
            cout << c;
        }
        cout << endl;
    }//打印下半部分
    cout << sy << endl;

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值