兔子的区间密码(思维)

题目大意:

链接: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 }
原文地址:https://www.cnblogs.com/letlifestop/p/10587101.html