1065 A+B and C (64bit) (20分)
long long int 类型的取值范围:[-2^63, 2^63-1]
A:[-2^63, 2^63]
B:[-2^63, 2^63]
C:[-2^63, 2^63]
if:A+B<-2^63 因为A和B的最小值是-2^63, 所以A+B的最小值是-2^64, 发生溢出,变成[0,2^63-1]。因为和的范围都超过了C的最大范围,所以肯定是true
if:A+B>=2^63 因为A和B能取到的最大值是2^63-1, 所以A+B的最大值是2^64-2, 发生溢出,变成[-2^63,-2]。 因为和的范围都超过了C的最小范围,所以肯定是false
最后一个测试点就是测试v[i].a<0 && v[i].b<0 && sum=0的情况
还有一个让我疑惑的点就是long long int 取不到2^63,但是A,B,C的范围来看是能取到的
于是我在边缘疯狂试探,最后发现当输入的是9223372036854775808时,它会自动变成9223372036854775807
比如在9223372036854775808 0 9223372036854775807这种情况下,明明应该是true,
但是它实际判断的是9223372036854775807+0不大于9223372036854775807,最后输出false
我去网上找了一圈,竟然全是一样的代码,我震惊,就没有一个人考虑边界情况吗?
虽然事实上测试点里也没有测试这种边界情况
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
struct num{
long long int a,b,c;
};
int main(){
int n; // 总数,小于10
scanf("%d",&n);
vector<num> v(n);
for(int i=0;i<n;i++){
scanf("%lld %lld %lld",&v[i].a,&v[i].b,&v[i].c);
long long int sum = v[i].a+v[i].b;
if(v[i].a>0 && v[i].b>0 && sum<0){
printf("Case #%d: true\n",i+1);
}
else if(v[i].a<0 && v[i].b<0 && sum>=0){
printf("Case #%d: false\n",i+1);
}
else if(sum>v[i].c){
printf("Case #%d: true\n",i+1);
}
else{
printf("Case #%d: false\n",i+1);
}
}
return 0;
}