1065 A+B and C (64bit) (20分)

PAT (Advanced Level) Practice

题目链接.

  • 编程题 1065 A+B and C (64bit) (20分)
    参考自《算法笔记》

Given three integers A, B and C in [−2^​63​​ ,2^​63​​ ], you are supposed to tell whether A+B>C.

Input Specification:
The first line of the input gives the positive number of test cases, T (≤10). Then T test cases follow, each consists of a single line containing three integers A, B and C, separated by single spaces.

Output Specification:
For each test case, output in one line Case #X: true if A+B>C, or Case #X: false otherwise, where X is the case number (starting from 1).

Sample Input:

3
1 2 3
2 3 4
9223372036854775807 -9223372036854775808 0

Sample Output:

Case #1: false
Case #2: true
Case #3: false

/*********************************************************************************************************************************/

思路:
由于 long long 的范围是 [-2^63, 2^63),因此题目中给出的两个整数相加有可能会溢出(正溢出或负溢出),直接进行大小判断会造成错误。在计算机组成原理中会指出,如果两个正数之和等于负数或是两个负数之和等于正数,那么就是溢出。对于溢出后的具体范围,可以进行如下分析:

  1. 当 A + B >= 2^63 时,显然有 A + B > C 成立,但 A + B 会因超过 long long 的正向最大值而发生正溢出。由于题目给定的 A 和 B 最大均为 2^63 - 1,故 A + B 最大为 2^64 - 2,因此使用 long long 存储正溢出后的值的区间为 [-2^63, -2](由(2^64 - 2) % (2^64) = -2 可得右边界 即去掉二进制数的第2^64位,剩下的就是溢出后剩下的数)。所以,当 A > 0, B > 0, A + B < 0 时为正溢出,输出 true.
  2. 当 A + B < -2^63 时,显然有 A + B < C 成立,但 A + B 会因超过 long long 的负向最小值而发生负溢出。由于题目给定的 A 和 B 最小均为 -2^63,故 A + B 最大为 -2^64,因此使用 long long 存储负溢出后的值的区间为 [0, 2^63 )(由(-2^64) % (2^64) = 0 可得左边界)。所以,当 A < 0, B < 0, A + B >= 0 时为负溢出,输出 false。
  3. 在没有溢出的情况下,当 A+B > C 时,输出 true;当 A + B <= C 时,输出 false。
    在这里插入图片描述

注意点:

  1. 经测试,数据中并没有 A 或 B 取到 2^63 的情况,因此题目中的数据范围可能是写错了,应该是 [-2^63, 2^63) 才更符合数据,否则就要用带负数的大整数运算了(因为 long long 存储 2^63 时会自动变成 -2^63,无法区分左右边界)。
  2. A + B 必须存放到 long long 型变量中才可与 C 进行比较,而不可以在 if 的条件中直接相加与 C 比较,否则会造成后两组数据错误。

参考代码

#include <cstdio> 
int main() {
	int T, tcase = 1;
	scanf ("%d", &T);
	while (T--) {
		long long a, b, c;
		scanf ("%lld%lld%lld", &a, &b, &c);
		long long res = a + b;	//res 存放 a + b 的结果
		bool flag;
		if (a > 0 && b > 0 && res < 0)	flag = true;	//正溢出为 true
		else if (a < 0 && b < 0 && res >= 0)  flag = false;	//负溢出为 false
		else if (res > c)  flag = true;	//无溢出时,A + B > C 时为 true
		else flag = false;				//无溢出时,A + B <= C 时为 false
		if (flag == true) {
			printf ("Case #%d: true\n", tcase++);
		} else {
			printf ("Case #%d: false\n", tcase++);
		}
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值