「PAT乙级真题解析」Basic Level 1027 打印沙漏 (问题分析+完整步骤+伪代码描述+提交通过代码)

题设给定了可用的符号数量, 要求输出能够打印出的最大的沙漏。 如果知道要输出几层, 问题会变得简单,就是一个循环加输出的操作。 所以我们需要先计算出要输出几层。

#算法#pat考试#数据结构#c语言#需求分析

Table of Contents

乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范。从小白开始逐步掌握用编程解决问题。

PAT (Basic Level) Practice 1027 打印沙漏

问题分析

题设给定了可用的符号数量, 要求输出能够打印出的最大的沙漏。 如果知道要输出几层, 问题会变得简单,就是一个循环加输出的操作。 所以我们需要先计算出要输出几层。

层数计算

  1. 方案一: 直接按照输出累加需要使用的符号数量, 找到小于等于可用符号量的最大使用值
  2. 方案二: 数学公式 以输入样例为例: 使用的符号数量为:
1 + 3 + 3 + 5 + 5 
= (1 + 3 + 5) * 2 - 1
= (1 + 5) * 3 / 2 * 2 - 1
= (1 + 5) * 3 - 1
= 17

替换为层数为:

(1 + row * 2 - 1) * row - 1 = 2 * row * row - 1

根据层数打印沙漏

我们需要知道需要输出多少个空格, 多少个符号以及用哪个符号输出(或者每层的宽度), 然后输出指定数量和空格和符号。 如果我们这样设计, 然后在外层就需要计算好每一层需要的空格和符号数目后传入。 算出层数之后, 从0开始到层数-1, 需要输出的空格就是对应的索引值。 每层的宽度 = 层数 * 2 - 1

完整步骤描述

  1. 获取输入: 可用的符号数量, 使用的符号
  2. 计算层数
  3. 计算每层宽度
  4. 从0到层数-1:
    • 计算空格数, 打印每层的形状
  5. 从层数-2到0:
    • 计算空格数, 打印每层的形状
  6. 输出剩余的可用符号数量

伪代码描述

  1. get input: available_amount, sign
  2. calculate layer_amount
  3. calculate width = layer_amount * 2 - 1
  4. for idx in range(0, layer_amount):
    • print_layer(sign=sign, space_amount=idx, width=width)
  5. for idx in range(layer_amount-1, -1, -1):
    • print_layer(sign=sign, space_amount=idx, width=width)
  6. print(available_amount - (2 * layer_amount * layer_amount - 1));

完整提交代码

/*
# 问题分析
题设给定了可用的符号数量, 要求输出能够打印出的最大的沙漏。
如果知道要输出几层, 问题会变得简单,就是一个循环加输出的操作。
所以我们需要先计算出要输出几层。
 
## 层数计算
1. 方案一: 直接按照输出累加需要使用的符号数量, 找到小于等于可用符号量的最大使用值
2. 方案二: 数学公式
以输入样例为例:
使用的符号数量为: 
 
1 + 3 + 3 + 5 + 5 
= (1 + 3 + 5) * 2 - 1
= (1 + 5) * 3 / 2 * 2 - 1
= (1 + 5) * 3 - 1
= 17
 
 
替换为层数为:
 
(1 + row * 2 - 1) * row - 1 = 2 * row * row - 1
 
 
## 根据层数打印沙漏
我们需要知道需要输出多少个空格, 多少个符号以及用哪个符号输出(或者每层的宽度),
然后输出指定数量和空格和符号。
如果我们这样设计, 然后在外层就需要计算好每一层需要的空格和符号数目后传入。
算出层数之后, 从0开始到层数-1, 需要输出的空格就是对应的索引值。
每层的宽度 = 层数 * 2 - 1
 
# 完整步骤描述
1. 获取输入: 可用的符号数量, 使用的符号
2. 计算层数
3. 计算每层宽度
4. 从0到层数-1:
    - 计算空格数, 打印每层的形状
5. 从层数-2到0:
    - 计算空格数, 打印每层的形状
6. 输出剩余的可用符号数量
 
# 伪代码描述
1. get input: available_amount, sign
2. calculate layer_amount
3. calculate width = layer_amount * 2 - 1
4. for idx in range(0, layer_amount):
    - print_layer(sign=sign, space_amount=idx, width=width)
5. for idx in range(layer_amount-1, -1, -1):
    - print_layer(sign=sign, space_amount=idx, width=width)
6. print(available_amount - (2 * layer_amount * layer_amount - 1));
*/
 
# include<stdio.h>
 
int calculate_layer_amount(int available_amount){
    for (int row = 0; row <= available_amount+1; row++) {
        if (2 * row * row - 1 > available_amount) {
            return row - 1;
        }
    }
    return 0;
}
 
int print_layer(char sign, int space_amount, int width){
    for (int i = 0; i < space_amount; i++){
        printf(" ");
    }
 
    int char_amount = width - space_amount * 2;
    for (int i = 0; i < char_amount; i++){
        printf("%c", sign);
    }
 
    printf("\n");
}
 
int main(){
    int available_amount;
    char sign;
    scanf("%d %c", &available_amount, &sign);
    
    int layer_amount = calculate_layer_amount(available_amount);
    int width = layer_amount * 2 - 1;
    for (int i = 0; i < layer_amount; i++){
        print_layer(sign, i, width);
    }
    for (int i = layer_amount - 2; i >= 0; i--){
        print_layer(sign, i, width);
    }
 
    printf("%d", available_amount - (2 * layer_amount * layer_amount - 1));
    return 0;
}
「PAT乙级真题解析」Basic Level 1027 打印沙漏 (问题分析+完整步骤+伪代码描述+提交通过代码) | 生活糖果