模拟题
稍微拔高一点的模拟题
【PAT1065】 A+B and C (64bit) (20分)
看本题之前我们来看一道类似的题目PAT 乙级
【PAT 乙级1011】 A+B 和 C (15分)
题目类似,唯一不同的地方如下:
给定区间 [−2^31 ,2^31] 内的 3 个整数 A、B 和 C,请判断 A+B 是否大于 C。
由于int整型范围为 [−2^31 ,2^31 - 1],因为超过int的范围且两个最大值或者两个最小值相加都未超过long long 8字节范围,故使用long long 类型
#include <iostream>
using namespace std;
//int范围-2147483648~2147483647
//本题最大的问题是两整数相加会溢出
int main()
{
int T, k = 0;
int n1, n2, n3; //错误,int范围是[2^-31, 2^31-1],但是题目要求是[2^-31, 2^31],故为long long
long long n;
cin >> T;
while (T--) {
cin >> n1 >> n2 >> n3;
n = n1 + n2;
if (n > n3) {
cout << "Case #" << (++k) << ": true" << endl;
}
else cout << "Case #" << (++k) << ": false" << endl;
}
return 0;
}
现在我们来看【PAT1065】 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
范围是 [−2^63 ,2^63],其他类似(唯一不足的是long long 类型是 [−2^63 ,2^63 - 1],但这不影响也不是重点)
问题是如何实现两个最大的long long 数相加或者两个最小的long long 数相加或者两个long long 类型数溢出咋办?
如果你想的是大数相加(用字符串实现!) 实现是可以实现,太复杂啦!且最后不一定Accept!(我劝你收手吧!)
那么如何实现这么大数呢?难道还有比long long 类型更大的类型吗?(想啥呢?)
既然无法实现两个大long long 相加,我们换个角度想想呗
正常的long long 还是可以相加的,仅仅只是两个太大的long long相加溢出或者两个太小的long long 相加溢出
那么我们就来考虑溢出的情况,溢出分为正溢出和负溢出
计算机组成原理中指出,如果两个正数之和等于负数或者两个负数之和等于正数,那么即是溢出!
即正溢出存在的情况: A > 0 B > 0 (A + B) < 0
即负溢出存在的情况: A < 0 B < 0 (A + B) >= 0
(具体原因不做解释,自行百度查询)
其他的情况:和正常情况一样
具体操作我们来看代码
#include <cstdio>
int main()
{
long long a, b, c;
int n;
scanf("%d", &n);
int i = 0;
bool flag;
while (n--) {
scanf("%lld %lld %lld", &a, &b, &c);
long long res = a + b;
if (a > 0 && b > 0 && res < 0) flag = true;//正溢出
//此情况下a + b 是绝对大于 c 的
else if (a < 0 && b < 0 && res >= 0) flag = false;//负溢出
//此情况下a + b 是绝对小于 c 的
else {//正常情况下
if (res > c)
flag = true;
else flag = false;
}
if (flag == true)
printf("Case #%d: true\n", ++i);
else
printf("Case #%d: false\n", ++i);
}
return 0;
}