题目大意:
链接:https://ac.nowcoder.com/acm/contest/543/C
来源:牛客网
题目大意:
有一只可爱的兔子被困在了密室了,密室里有两个数字,还有一行字:
只有解开密码,才能够出去。
可爱的兔子摸索了好久,发现密室里的两个数字是表示的是一个区间[L,R]
而密码是这个区间中任意选择两个(可以相同的)整数后异或的最大值。
比如给了区间[2,5] 那么就有2 3 4 5这些数,其中 2 xor 5=7最大 所以密码就是7。
兔子立马解开了密室的门,发现门外还是一个门,而且数字越来越大,兔子没有办法了,所以来求助你。
提示:异或指在二进制下一位位比较,相同则 0 不同则 1
例如2=(010)22=(010)2 5=(101)25=(101)2
所以2 xor 5=(111)2=75=(111)2=7
区间选两个数异或最大。
具体思路:
首先对区间端点进行二进制分解,然后从最长二进制开始,发现第一个不同的就停止,记录此时的下标为i,然后最终答案就是(1<<i)-1.
首先,我们从最长的第一位开始是为了保证数是在这个区间之间,然后找到一个不同的,只能是r端点对应的此时的二进制位为1,而l端点对应的此时的二进制位0,然后(1<<i)-1就是最终答案了,这样既能
保证是区间内的数,又能保证是最大的
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2100; 5 ll a[maxn]; 6 ll b[maxn]; 7 ll cal(ll l,ll r){ 8 ll num1=0,num2=0; 9 memset(a,0,sizeof(a)); 10 memset(b,0,sizeof(b)); 11 while(l){ 12 a[++num1]=l%2; 13 l/=2; 14 } 15 while(r){ 16 b[++num2]=r%2; 17 r/=2; 18 } 19 ll len=0; 20 for(ll i=max(num1,num2);i>=0;i--){ 21 if(a[i]!=b[i]){ 22 len=i; 23 break; 24 } 25 } 26 return (1ll<<(len))-1ll; 27 } 28 int main(){ 29 int T; 30 scanf("%d",&T); 31 while(T--){ 32 ll l,r; 33 scanf("%lld %lld",&l,&r); 34 printf("%lld ",cal(l,r)); 35 } 36 return 0; 37 }