题目链接https://ac.nowcoder.com/acm/contest/543/C
题意:闭区间L,R中,任选两数异或,求最大值。
解 首先,L,R,可以被看成两个01序列,且R>=L。思考这样一个事情:如果(int)L,R/2不相等,那么最大值就确定了,因为在这种情况下将他们大小比较一下,最高位R一定是1,L一定是0,所以R一定>=100...(n个0),L一定<=011...(n个1),所以在这种情况下,最大值便是这两个数异或,得11(n+1个1)。那么,如果L,R的最高位一样呢,那么L,R中异或的最大值的最高位一定是0了,所以这个问题就变成了去掉最高位后,按上述规则找最大值。当然,要考虑到,如若L=R,最大值为0,这种情况也是满足上述说明的。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll l,r;
int cnt1,cnt2;
int a[100],b[100];
int t;
bool flag=false;
ll solve(int x){
long long ans=1;
for(int i=1;i<=x;i++)ans*=2;
return ans;
}
int main(){
scanf("%d",&t);
while(t--){
memset(a,0,sizeof(a));memset(b,0,sizeof(b));
scanf("%lld%lld",&l,&r);
while(l){
a[++cnt1]=(l%2);
l/=2;
}
while(r){
b[++cnt2]=(r%2);
r/=2;
}
if(cnt2>cnt1){
int t=cnt2-cnt1;
for(register int i=1;i<=t;i++)a[++cnt1]=0;
}
for(register int i=cnt2;i>=1;i--){
if(a[i]==0&&b[i]==1){printf("%lld\n",solve(i)-1);flag=true;break;}
}
if(flag==false)printf("0\n");
flag=false;
cnt1=0,cnt2=0;
// for(register int i=cnt2;i>=1;i--)printf("%d",a[i]);
// printf("\n");
// for(register int i=cnt2;i>=1;i--)printf("%d",b[i]);
}
}
浙公网安备 33010602011771号