nyoj744 蚂蚁的难题(一)

蚂蚁的难题(一)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

小蚂蚁童鞋最近迷上了位运算,他感觉位运算非常神奇。不过他最近遇到了一个难题:

给定一个区间[a,b],在区间里寻找两个数x和y,使得x异或y最大。来,帮帮他吧!

输入
有多组测试数据(以EOF结尾)。
每组数据输入两个数a,b.(0<=a
输出
输出a到b之间,异或最大的值。
样例输入
1 2
8 9
样例输出
3
1
来源

蚂蚁系列

  

     解题思路:求一个区间[a,b]中任意两个数异或的最大值:

先做a^b得到一个数,该数二进制的第一个1(位置为q)一定产生于a的1和b的0做异或(因为a>b),所以q以上的位置a,b都是1,无法调动。但q以下的位置的0无论产生于a的1,b的1或是a的0,b的0,都可以对应调小a或者调大b来使得最终异或的结果为1111111……i.e. 2^cnt-1。
      错误思路:暴力求出任意两个数的二进制,再求出异或值,枚举找出最大的。。。。。超时........当时对异或完全没有概念,没思路啊,,,,


错误代码: 

       

#include
using namespace std;
int a[100]= {0},b[100]= {0},ans,k1,k2,sum;
long long pp(long long aa,long long bb)
{
    k1=0;
    k2=0;
    sum=0;
    while(aa)
    {
        a[k1++]=aa%2;
        aa/=2;
    }
    while(bb)
    {
        b[k2++]=bb%2;
        bb/=2;
    }
    ans=k1>k2?k1:k2;
    for(int i=0; imax)
                    max=pp(i,j);
            }
        printf("%lld\n",max);
    }
    return 0;
}

正解:

#include
#include
#include
#include
using namespace std;
int main()
{
   long long a,b,x,ans,sum;
   while(~scanf("%lld%lld",&a,&b))
   {
       ans=0;
       x=a^b;//求a,b的异或值
       while(x)
       {
           ans++;//找出二进制中一的个数
           x/=2;
       }
       sum=pow(2,ans)-1;
       printf("%lld\n",sum);
   }
   return 0;
}


你可能感兴趣的:(nyoj)