nyoj744 蚂蚁的难题(一)

蚂蚁的难题(一)

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

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

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

输入
有多组测试数据(以EOF结尾)。
每组数据输入两个数a,b.(0<=a<b<2^63)
输出
输出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<bits/stdc++.h>
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; i<ans; i++)
    {
        if(a[i]==b[i])
            sum+=0;
        else
            sum+=pow(2,i);
    }
    return sum;
}
int main()
{
    long long x,y,i,j,max;
    while(~scanf("%lld%lld",&x,&y))
    {
        max=0;
        for(i=x; i<=y; i++)
            for(j=i+1; j<=y; j++)
            {
                if(pp(i,j)>max)
                    max=pp(i,j);
            }
        printf("%lld\n",max);
    }
    return 0;
}

正解:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值