本来没打算写这道题的解法的,但是有朋友问怎么做,那我今天就把这道题的解法写出来。
首先要明白异或的概念,其次计算机在做异或运算的时候,就是0,1的比较。所以,第一步,我们要考虑a,b的二进制。
具体思路就是:
1、首先求出a,b的二进制位数。为什么要求出二进制位数?原因很简单,直观啊,而且异或运算的最大结果不会超过b的二进制位数。距离来说:
如果a为1011,b为100110,那么他们异或的值位数一定不会超过b的位数,即6位,而且最大也就是111111,。
2、知道了异或值可能的最大位数,那么就容易计算最大值是多少?很显然是位数个1,但是,这又受到a的影响,a对它的影响,可以看出,当a的位数小于b的位数时,那么最大值就是b位数个1,如果a的位数和b的位数相同,那么从高位开始比较,直到a的某一位和b的同一位置不想同,那么,很明显,这就相当于吧前面的截掉,邱泽两个新的数的异或最大值,而且,根据1,可以直接得到最大异或值。
在思路2中,为什么是这样的,是这样分析的:
假设b的位数为6,那么b一定大于等于100000,如果a和不的位数不相同,那么一定能找到一个数c:11111,位数为5,个1,这个c一定小于b,一定大于等于a,那么就可以得到最大异或值了。
位数相同,那么就向后找。分析同上。
代码比较简单:
int al = 0;
int bl = 0;
long tmpa = a;
long tmpb = b;
if (a == 0)
{
al = 1;
}
else
{
while (tmpa > 0)
{
al++;
tmpa = tmpa >> 1;
}
}
if (tmpb == 0)
{
bl = 1;
}
else
{
while (tmpb > 0)
{
bl++;
tmpb = tmpb >> 1;
}
}
long max = 0L;
if (al != bl)
{
max = (1L << bl) - 1;
}
else
{
for (int i = bl - 1; i >= 0; i--)
{
tmpb = (b >> i) % 2;
tmpa = (a >> i) % 2;
if (tmpb == 1)
{
if (tmpb != tmpa)
{
max = (1L << (i+1) )- 1;
break;
}
}
}
}
return max;
ok,到此结束。