【PAT乙级】1027 打印沙漏 (20 分)

题目传送门 

https://pintia.cn/problem-sets/994805260223102976/problems/994805294251491328

 

这道题看起来不难,实际上也确实不难

我们观察可以发现要打印的沙漏可以看成两个同顶角的三角形组成。

如果看成数列的话,那么最顶上a1 = 1

之后就有递推式 an = 2*(1+2*(n-1))  其中n是我们算的那一行

我们在求行数的时候只要用给定的符号数量每次减去那一行有的符号,如果减完之后符号数量小于零,那么就将操作回滚,退出循环;如果减完之后大于零就继续减

打印沙漏的时候后面的空格是不用打印的,不过打印的话也不难就是了,就是把打印前面的操作再来一遍

从顶行到三角形的顶角那一行,每一行的空格数都是加一的

代码如下

 

#include <stdio.h>
//有递推式, a1 = 1 an = 2 * (a1 + 2*(n-1))


int main(){
    int n;
    char b;
    scanf("%d %c", &n, &b);
    int row=1;    //行数
    n -= 1;
    int count = 2;
    while(1){
        n -= (2*(1 + 2 * (count - 1))); //递推公式
        if(n < 0){
            n += (2*(1 + 2 * (count - 1)));
            break;
        }
        row++;  //行数加一
        count++;
    }
    //打印沙漏
    int c = count-1;    //c是指定的输出字符最多的行数
    int sumBlank = 0;   //每行前面的空格数,逐行加一
    for(;c > 1; c-=1){
        for(int j=0; j < sumBlank; j++){
            printf(" ");
        }
        sumBlank++;
        for(int k=0; k<(1 + 2 * (c- 1)); k++){
            printf("%c", b);
        }
        printf("\n");
    }
    for(int j=0; j<sumBlank; j++){
        printf(" ");
    }
    printf("%c\n", b);
    sumBlank--;
    for(c = 2 ;c < count; c++){
        for(int j=0; j<sumBlank; j++){
            printf(" ");
        }
        sumBlank--;
        for(int k=0; k<(1 + 2 * (c- 1)); k++){
            printf("%c", b);
        }
        printf("\n");
    }
    printf("%d", n);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值