注意点:
a-b可能会溢出
至于,为什么牛客网有的没有考虑可能溢出也AC了,似乎是因为牛客的测试数据不够严格。
解法1
用64位的数据进行扩展,这样就能防止溢出了。
思路:
- 1)aa-bb<0,由于是有符号位右移。最终,右移63位,得到的是-1,那么乘以-1,修正,那样正好能输出solution[1],也就是后者。
- 2)aa-bb>0,由于是有符号位右移。最终,右移63位,得到的是0。乘以-1,还是能输出solution[0],也就是前者。
#include<bits/stdc++.h>
using namespace std;
int solution[2];
int test(int a,int b)
{
//防止a-b溢出
long long aa=(long long)a;
long long bb=(long long)b;
return -1*(int)((aa-bb)>>63);
}
int main()
{
while(cin>>solution[0]>>solution[1])
{
cout<<solution[test(solution[0],solution[1])]<<endl;
}
return 0;
} 解法2
用64位的数据进行扩展,这样就能防止溢出了。
思路:
- 1)同方法1理,获取aa-bb的正负
- 2)cc=-1的时候,aa-(aa-bb)(-1)(-1)=bb,后者
cc=0的时候,aa-(aa-bb)(-1)0=aa,前者
#include<bits/stdc++.h>
using namespace std;
int solution[2];
long long test(int a,int b)
{
//防止a-b溢出
long long aa=(long long)a;
long long bb=(long long)b;
long long int cc = (aa-bb)>>63;
return aa-(aa-bb)*(-1)*cc;
}
int main()
{
while(cin>>solution[0]>>solution[1])
{
cout<<test(solution[0],solution[1])<<endl;
}
return 0;
} 解法3(推荐用)
虽然前面两种,想出来的时候能够AC,但是有一说一,要是面试官问你
a和b是64位的,那就无法用刚刚那样的扩展方式来解决溢出了。
所以,前两种解决可行,但是个人觉得还不够好。所以去网上找了找其他方法学习。
发现,《程序员代码面试指南》一书中这种解法不错。
参考,贴到了下面
#include<bits/stdc++.h>
using namespace std;
int solution[2];
int flip(int n)
{
return n ^ 1;
}
int sign(int n)
{
return flip((n >> 31) & 1);
}
int getMax2(int a,int b)
{
int c = a - b;
int sa=sign(a);
int sb=sign(b);
int sc=sign(c);
int difSab= sa^sb;
int sameSab= flip(difSab);
int returnA= difSab*sa+sameSab*sc;
int returnB= flip(returnA);
return a*returnA+b*returnB;
}
int main()
{
while(cin>>solution[0]>>solution[1])
{
cout<<getMax2(solution[0],solution[1])<<endl;
}
return 0;
} 
京公网安备 11010502036488号