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

[PAT练级笔记] 09 Basic Level 1011

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

Table of Contents

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

PAT乙级BasicLevelPractice 1011

问题分析

题目给定3个整数A, B, C, 三个数取值范围都是 [−2^31, 2^31]. 要求判断A+B是否大于C.

32位机器能表示的长度是32位, 整数有正有负, 1位给符号位, 31位给数值. 所以取值范围中的"2^31"意味着本题需要重点考虑整型的表示范围, 防止"数值溢出".

为了避免数值溢出, 我们需要先分析哪些情况会数值溢出。

数值溢出的情况

A, B, C三个数本身不会数值溢出, 但是由于我们需要计算A+B, 所以要考虑的是A+B可能数值溢出的情况. A+B数值溢出的情况有:

  1. 大正数+大正数导致结果过大溢出; (A>0, B>0)
  2. 大负数+大负数导致结果过小溢出; (A<0, B<0)

其他情况可以直接比较A+B和C的大小。

避免数值溢出

以A>0, B>0的情况为例, 我们需要做的是避免"A+B"的运算, 同时达到比较(A+B)和C的目的.

  1. 如果C是负数, 则由正负性可以直接知道: A+B > C
  2. 如果C是正数, 则 (A+B)与C的比较可以转换为 B与(C-A)的比较.

(A<0, B<0的情况同理)

完整描述步骤:

  1. 如果是A+B可能数值溢出的情况(A>0, B>0 或者A<0, B>0), 考虑C的正负性来避免 (A+B)的运算;
  2. 如果不是A+B可能数值溢出的情况, 直接比较(A+B)和C的大小

伪代码描述步骤

  1. if(A > 0 and B > 0), consider value of C:

    • if C > 0, compare (B - C) and A;
    • else because C <= 0 < A+B, return true
  2. if(A < 0 and B < 0), consider value of C:

    • if C < 0, compare (B - C) and A;
    • else because C >= 0 > A+B, return false
  3. else compare (A+B) and C

完整提交代码

/*
问题分析:
题目给定3个整数A, B, C, 三个数取值范围都是 [−2^31, 2^31]. 要求判断A+B是否大于C.
 
32位机器能表示的长度是32位, 整数有正有负, 1位给符号位, 31位给数值. 
所以取值范围中的"2^31"意味着本题需要重点考虑整型的表示范围, 防止"数值溢出".
 
为了避免数值溢出, 我们需要先分析哪些情况会数值溢出。
# 数值溢出的情况
A, B, C三个数本身不会数值溢出, 但是由于我们需要计算A+B, 所以要考虑的是A+B可能数值溢出的情况.
A+B数值溢出的情况有: 
1. 大正数+大正数导致结果过大溢出; (A>0, B>0)
2. 大负数+大负数导致结果过小溢出; (A<0, B<0)
 
其他情况可以直接比较A+B和C的大小。
 
# 避免数值溢出
 
以A>0, B>0的情况为例, 我们需要做的是避免"A+B"的运算, 同时达到比较(A+B)和C的目的.
如果C是负数, 则由正负性可以直接知道: A+B > C
如果C是正数, 则 (A+B)与C的比较可以转换为 B与(C-A)的比较.
(A<0, B<0的情况同理)
 
# 完整描述步骤:
1. 如果是A+B可能数值溢出的情况(A>0, B>0 或者A<0, B>0), 考虑C的正负性来避免 (A+B)的运算;
2. 如果不是A+B可能数值溢出的情况, 直接比较(A+B)和C的大小
 
# 伪代码描述步骤
1. if(A > 0 and B > 0), consider value of C:
    - if C > 0, compare (B - C) and A;
    - else because C <= 0 < A+B, return true
 
2. if(A < 0 and B < 0), consider value of C:
    - if C < 0, compare (B - C) and A;
    - else because C >= 0 > A+B, return false
 
3. else compare (A+B) and C
    
*/
 
int compare_A_plus_B_with_C(int A, int B, int C){
    if (A > 0 && B > 0) {
        if (C > 0) {
            return B > C - A;
        } else {
            return 1;
        }
    }
    if (A < 0 && B < 0) {
        if (C < 0) {
            return B > C - A;
        } else {
            return 0;
        }
    }
    
    return (A + B) > C;
}
 
 
 
int main(){
    int case_amount;
    scanf("%d", &case_amount);
    
    
    int A;
    int B;
    int C;
    int compared_result = 0;
    for (int i = 0; i < case_amount; i++){
        scanf("%d %d %d", &A, &B, &C);
        compared_result = compare_A_plus_B_with_C(A, B, C);
        if (compared_result == 0){
            printf("Case #%d: false\n", i+1);
        } else {
            printf("Case #%d: true\n", i+1);
        }
    }
    
    return 0;
}