AOJ-problem-829

                                                                       最大的位或

Description
B君和G君聊天的时候想到了如下的问题。
给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大。
其中|表示按位或,即C、 C++、 Java中的|运算。


Input
包含至多10001组测试数据。
第一行有一个正整数,表示数据的组数。
接下来每一行表示一组数据,包含两个整数 l,r。保证 0 <= l <= r <= 10^18。


Output
对于每组数据输出一行,表示最大的位或。

思路:
l<r,化为二进制有两种情况:1.L和R等长。2.L长度小于R。
情况2是我很乐意见到的,因为我可以取到一个与L同位数但全为1而且一定小于R的L1.
因此对于情况1,我们很乐意从L的某一位置开始发现满足情况2。
代码:
#include<stdio.h>

int memlength(long long n)                 //十进制转化为二进制
{
	int flag=0;
	while(n)
	{
		n/=2;
		flag++;
	}
	return flag;
}

int main()
{
	int n;
	int a[100000]={0},b[100000]={0};
	scanf("%d",&n);
	while(n--)
	{
		long long l,r,L,R;
		scanf("%lld",&L);
		scanf("%lld",&R);
		l=L;
		r=R;
		int length=memlength(L);
		for(int i=1;i<=length;i++)
		{
			a[i]=l%2;
			l=l/2;
		}
		length=memlength(R);
		for(int i=1;i<=length;i++)
		{
			b[i]=r%2;
			r=r/2;
		}
		if(memlength(R)>memlength(L))          //情况2
			for(int i=memlength(R);i>=1;i--)
			{
				b[i]=1;
			}
		else if(memlength(R)==memlength(L))    //情况1
		{
			int i=memlength(R);
			while(a[i]==b[i])
				i--;                   //从这个位置a[i]!=b[i]而且一定是a[i]=0,b[i]=1
			for(i;i>=1;i--)
			{
				b[i]=1;                //之后所有b[i]都有办法取到1 ^_^
			}
		}
		long long sum=0;
		for(int i=memlength(R);i>=1;i--)
		{
			sum*=2;
			if(b[i])
				sum+=2;
		}
		printf("%lld\n",sum/2);
	}
	return 0;
}
	

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值