当前位置:   article > 正文

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

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

一、题目描述

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

*****
 ***
  *
 ***
*****
  • 1
  • 2
  • 3
  • 4
  • 5

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

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

输入格式:

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

输出格式:

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

输入样例:

19 *

输出样例:

*****
 ***
  *
 ***
*****
2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

二、题目分析

大小为0的沙漏需要1个符号
大小为1的沙漏需要1+23个符号
大小为2的沙漏需要7+2
5个符号
使用数组a[23]记录大小为0,1,2…22的沙漏所需符号
a[22]=1057

首先遍历数组a,找到当前符号个数能组成的最大沙漏
然后按格式输出

三、思路与代码

1.思路

  • 得到第i个沙漏所需的符号数,并找到输入的当前符号个数能组成的最大沙漏
    //找到当前输入符号个数所能组成的最大沙漏大小
    //如,若输入18,则pos=2,最大沙漏大小为2
    int pos = -1;
    for (int i = 0; i < 22; i++)
    {
        if (a[i] <= N && a[i + 1] > N)
        {
            pos = i;
            break;
        }
    }
    int n = pos;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 按格式输出,可以分为前半部分和后半部分输出。如输入19 *时,前三行为前半部分,后两行为后半部分。
  • 此时沙漏大小为2,(沙漏大小为n)
  • 前半部分各行空格依次为0,1,2,输出符号依次为5,3,1
  • 所以前半部分规律为 空格数=行数,符号数=(2*n+1)-行数
  • 后半部分规律同上
*****
 ***
  *
 ***
*****
2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 测试点0,测试点3 考察的是<7个时的特殊情况,
    即 输入1-6之间时,输出的个数
  • 测试点1,测试点2 考察的是>7个时的情况
    %c是随意替换的 测试点1 2错误原因就是这个
  • 需要注意的是,在所有的打印中,要求在且仅在每行要打印的符号前面打印空格,后面不能打印空格。

2.代码

#include <stdio.h>
#include <iostream>

using namespace std;

int a[23];//存放第0,1...n个沙漏需要的符号个数
//第0个沙漏需要1个符号
//第1个沙漏需要7个符号
void init()  //初始化数组a
{
    //得到从小到大能够组成沙漏形状需要的符号数
    //如 a[0]需要1个沙漏符号
    // a[1]需要 1 + 2 * 3 = 7 个
    // a[2]需要 7 + 2 * 5 = 17个
    // a[n]需要 a[i-1] + 2 * (2*n+1) 个沙漏符号
    a[0] = 1;
    for (int i = 1; i < 23; i++)
    {
        a[i] = a[i - 1] + 2 * (2 * i + 1);
    }
    return;
}
int main()
{
    init();

    int N;
    cin >> N;
    char c;
    cin >> c;

    //找到当前输入符号个数所能组成的最大沙漏大小
    //如,若输入18,则pos=2,最大沙漏大小为2
    int pos = -1;
    for (int i = 0; i < 22; i++)
    {
        if (a[i] <= N && a[i + 1] > N)
        {
            pos = i;
            break;
        }
    }
    int n = pos;
    //第0个对应1行
    //第1个对应3行
    //第2个对应5行
    //第3个对应7行
    //第n个要输出2*n+1行

    //输出符号
    
    //特殊情况特殊处理
    if (n == 0)
    {
        printf("%c\n%d", c, N - a[0]);
        return 0;
    }

    //前半部分输出
    for (int i = 0; i <= (2 * n + 1) / 2; i++)
    {
        int blank = i; //每行的空格数
        int charnum = (2 * n + 1) - 2 * i; //每行需要输入的字符数

        //输出空格
        for (int j = 0; j < blank; j++)
        {
            printf(" ");
        }

        //输出字符
        for (int j = 0; j < charnum; j++)
        {
            printf("%c", c);
        }
        printf("\n");
    }

    //后半部分输出
    for (int i = 1; i <= (2 * n + 1) / 2; i++)
    { 
        int blank = n - i;//每行输出空格数
        int charnum = 2 * i + 1;//每行输出字符数

        for (int j = 0; j < blank; j++)
        {
            printf(" ");
        }

        for (int j = 0; j < charnum; j++)
        {
            printf("%c", c);
        }

        printf("\n");
    }

    printf("%d", N - a[n]);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

四、结果

在这里插入图片描述
之前提交的时候测试点1,2一直过不去,后来发现是对特殊情况,输入1-6之间时,默认输出符号为*,但输出符号应为%c,是任意值。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/935735
推荐阅读
相关标签
  

闽ICP备14008679号