付忠庆的练习小笔记-Codeforces #276 Div2 C

原题链接 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 }

 

posted @ 2014-11-12 21:19  付忠庆  阅读(141)  评论(0编辑  收藏  举报