注意点:
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; }