「PAT乙级真题解析」Basic Level 1017 A除以B (问题分析+完整步骤+伪代码描述+提交通过代码)

题目给定一个大正整数A, 一个1位正整数B, 要求输出A除以B的商数Q和余数R. 从数学的角度, 商数Q和余数R可以直接由除法求得. 但显然这道题目有无法直接进行除法得到结果的因素: 整数过大, 用整型存储会导致数值溢出...

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

Table of Contents

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

PAT乙级BasicLevelPractice 1017 A除以B

问题分析

题目给定一个大正整数A, 一个1位正整数B, 要求输出A除以B的商数Q和余数R. 从数学的角度, 商数Q和余数R可以直接由除法求得. 但显然这道题目有无法直接进行除法得到结果的因素: 整数过大, 用整型存储会导致数值溢出

于是我们可以想到用字符串存储大整数(也可以用整型数组存储各个数位上的数字, 但是读数的时候会麻烦些, 需要按照字符读入然后转换成数字) 然后模拟除法来求得商数和余数.

模拟除法

回到小学数学的"短除法", 形式如下:

  __3_____        __33____
3/ 100          3/ 100
    9       ->      9
  -------         -------
    1               10
                     9
                  -------
                     1

所以, 100 / 3 = 33 ······ 1

完整地描述步骤

  1. 读入数据

  2. 初始化被除数为字符, 设置字符数组存储商

  3. 循环获取每个数位上的数字. 进行如下操作:

    • 被除数 = 被除数 * 10 + 当前数字
    • 商数末尾加上 "当前被除数 / 除数"的商
    • 被除数 = "当前被除数 / 除数"的余数
  4. 输出商数和余数

    • 考虑到商数可能是0开头, 所以要从第一个非'0'的位置开始输出
    • 余数就是最后的被除数

伪代码描述

  1. get big number A as string, get integer B

  2. 初始化 被除数 = 0, 商 = ''

  3. for each_char in A: 被除数 = 被除数 * 10 + number(each_char) 当前商 = 被除数 / 除数 当前余数 = 被除数 % 除数 商 = 商 + 当前商 (字符串添加字符) 被除数 = 余数

  4. 设置 "是否输出的标志位" should_print = 0

  5. for each_char in 商:

    • if should_print == 0 and each_char != '0':
      • should_print = 1
    • if should_print:
      • print(each_char)
  6. print(" " + B)

完整提交代码

/*
# 问题分析
 
提出给定一个大正整数A, 一个1位正整数B, 要求输出A除以B的商数Q和余数R.
从数学的角度, 商数Q和余数R可以直接由除法求得. 但显然这道题目有无法直接进行除法得到结果的因素: 整数过大, 用整型存储会导致数值溢出
 
于是我们可以想到用字符串存储大整数(也可以用整型数组存储各个数位上的数字, 但是读数的时候会麻烦些, 需要按照字符读入然后转换成数字)
然后模拟除法来求得商数和余数.
 
## 模拟除法
 
回到小学数学的"短除法", 形式如下:
 
  __3_____        __33____
3/ 100          3/ 100
    9       ->      9
  -------         -------
    1               10
                     9
                  -------
                     1
所以, 100 / 3 = 33 ······ 1
 
# 完整地描述步骤
 
1. 读入数据
2. 初始化被除数为字符, 设置字符数组存储商
3. 循环获取每个数位上的数字. 进行如下操作:
    - 被除数 = 被除数 * 10 + 当前数字
    - 商数末尾加上 "当前被除数 / 除数"的商
    - 被除数 = "当前被除数 / 除数"的余数
 
4. 输出商数和余数
    - 考虑到商数可能是0开头, 所以要从第一个非'0'的位置开始输出
    - 余数就是最后的被除数
 
 
 
# 伪代码描述
 
1. get big number A as string, get integer B
2. 初始化 被除数 = 0, 商 = ''
3. for each_char in A:
    被除数 = 被除数 * 10 + number(each_char)
    当前商 = 被除数 / 除数
    当前余数 = 被除数 % 除数
    商 = 商 + 当前商 (字符串添加字符)
    被除数 = 余数
4. 设置 "是否输出的标志位" should_print = 0
5. for each_char in 商:
    if should_print == 0 and each_char != '0':
        should_print = 1
    if should_print:
        print(each_char)
        
6. print(" " + B)        
*/
 
int main(){
    char number[1001];
    int dividee;
    scanf("%s %d", number, &dividee);
    int number_size = 0;
    int divider = 0;
    int started = 0;
    for (int i = 0; number[i]; i++){
        number_size++;
    }
    
    if (number_size == 1){
        divider = (int)number[0] - 48;
        printf("%d %d", divider / dividee, divider % dividee);
        return 0;
    }
    
 
    for (int i = 0; i < number_size; i++){
        divider = divider * 10 + ((int)number[i] - 48);
        int divided = divider / dividee;
        if(!(divided == 0 && i == 0)){
            printf("%d", divided);
        }
        divider = divider % dividee;
    }
    
    printf(" %d", divider);
 
}
 
「PAT乙级真题解析」Basic Level 1017 A除以B (问题分析+完整步骤+伪代码描述+提交通过代码) | 生活糖果