天梯赛习题:正整数A+B

  • 题目描述
  • 解题思路
  • 数据结构
  • 算法
  • 细节
  • 参考答案
  • 测试用例
  • 小结


题目描述

题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。

输入格式:
输入在一行给出A和B,其间以空格分开。问题是A和B不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。

注意:我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。

输出格式:
如果输入的确是两个正整数,则按格式A + B = 和输出。如果某个输入不合要求,则在相应位置输出?,显然此时和也是?。

输入样例1:
123 456

输出样例1:
123 + 456 = 579

输入样例2:
22. 18

输出样例2:
? + 18 = ?

输入样例3:
-100 blabla bla…33

输出样例3:
? + ? = ?

解题思路

数据结构
  1. 用变量a, b存储输入的被加数和加数。
  2. 用变量r_a, r_b存储判别合法性后的被加数和加数。这两个变量的取值是:如果合法,也就是是数字字符串,且数值落在[1, 1000]区间内,那么值为数字字符串;否则值为字符串‘?’。
算法
  1. 把输入的一行在第一个空格处分割成被加数a和加数b。
  2. 判别被加数a是否合法,若合法则令r_a = a,否则令r_a=’?’。判别加数b是否合法,若合法则令r_b = b,否则令r_b=’?’ 。
  3. 求r_a + r_b,如果两者之一或全部等于’?’,则结果r_c = ‘?’,否则r_c赋值为两个整数相加之和。
细节
  1. 题目描述指出,“我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。”这表明,输入行的开头没有空格。

参考答案

#num_str是数字字符串吗,大于等于1且小于等于1000吗?
def among_1_1000(num_str):
    for s in num_str:
        if not s.isdigit():
            return False
    return 1<=int(num_str)<=1000

a, b = input().split(maxsplit=1)  #向名字为maxsplit的形参传入实参值1。这是关键字参数的写法。
r_a = a
if not among_1_1000(a):
    r_a = '?'

r_b = b
if not among_1_1000(b):
    r_b = '?'

if r_a != '?' and r_b != '?':
    result = str(int(r_a) + int(r_b))
else:
    result = '?'

print('%s + %s = %s'%(r_a, r_b, result))

测试用例

  1. 题目描述给出的第一组测试用例覆盖了被加数和加数都合法的情形。
  2. 题目描述给出的第二组测试用例覆盖了被加数不合法,加数合法的情形。
  3. 题目描述给出的第三组测试用例覆盖了被加数和加数都不合法的情形。而且,被加数是一个合法的整数,只是没有落在[1, 1000]区间内。
  4. 操作数落在区间边界上的情形。
    样例输入
    1 1000
    样例输出
    1 + 1000 = 1001
  5. 操作数落在合法值区间外侧的情形。
    样例输入
    0 10001
    样例输出
    ? + ? = ?

小结

  1. 拼题A网站上,本题的通过率是16%。这与多数人采用C/C++答题有关系。用Python答题更容易得分。这是因为运用Python提供的函数,程序员关注的细节更少,开发效率更高。
  2. 对于input().split(maxsplit=1),讲解如下:
    (1)首先执行input(),从标准输入(一般情况下是键盘)读入一行,结果存为字符串s。
    (2)接着执行split(),在输入行的第一个空格处把字符串s分隔处两部分,即被加数和加数。
    (3)括号内的maxsplit=1是关键字参数的写法。作用是,向名字为maxsplit的形参传入实参值1。效果是,对字符串s执行1次分割操作,即在输入行的第一个空格处把字符串s分隔成两部分。比如,"1 100 abc"将被分割为“1”和“100 abc”,100后面的空格没有用作分割符。