原题链接 http://codeforces.com/contest/485/problem/C
题意:给出一个区间 l~r 求这个区间内的数中转换成2进制含‘1’最多的数,若有多组解,则输出最小的那个数,例如:
1(10) = 1(2)
2(10) = 10(2)
3(10) = 11(2)
4(10)= 100(2)
5(10) = 101(2)
6(10) = 110(2)
7(10) = 111(2)
8(10) = 1000(2)
9(10) = 1001(2)
10(10) = 1010(2)
input
3
1 2
2 4
1 10
output
1
3
7
结果很显然不做赘述;
1-遍历一遍显然不合适,容易超时,所以我们这里采用一种"跳着"'向下寻找'的思维
“跳着” 是指我这次寻找的数有 i 个 1 那么下一次寻找不可能寻找一个 j<i的数,(7->8就很明显)
'向下寻找'是指由小向大寻找;
为了满足上述思想
我们先假设r是我们找的那个 我们就把他先转换成二进制 ,从第一位开始遍历如果不是1则变成1,直到r>l 那么这个状态上一次的r就是目标数,(---此时你可以画一画试一试想想这个算法的奇妙之处,以及如何满足"跳着"'向下寻找'的)..
附代码
1 #include <iostream> 2 typedef long long LL; 3 using namespace std; 4 int main() 5 { 6 int t; 7 cin>>t; 8 while(t--) 9 { 10 LL li,ri; 11 cin>>li>>ri; 12 LL tt=1; 13 while((li|tt)<=ri) 14 { 15 li=li|tt; 16 tt=(tt<<1); 17 } 18 cout<<li<<endl; 19 } 20 }