BOJ 1578 Maximum

Maximum

Accept:5     Submit:24

Time Limit:1000MS     Memory Limit:65536KB

Description

Define f(x) as the number of 1s under base 2. For instance, f(5)=2 for (5)10=(101)2, and f(7)=3 for (7)10=(111)2.

Given [A,B], you're required to figure out the maximum f(x) where x is in range [A,B].

Input Format

An integer T(T≤100) will exist in the first line of input, indicating the number of test cases.

Each test case consists of two integers A,B(1≤A,B≤108).

Output Format

Output the maximum f(x) for each test case, one per line.

Sample Input

1

4 6

Sample Output

2

 

新生排位赛第四场的B题,当时还是费了一点脑筋的,比赛到两个多小时的时候才想出来。

题意大概是:定义了一个函数f(x),表示x的二进制表示中1的个数。给定一个区间[A,B],求区间内f(x)的最大值。

刚开始总想着把所有数的f(x)都求出来,然后再在给定的区间内搜索。后来试了几种方法,把所有的f(x)都求出来最快的算法还要1.5s左右,必然超时,于是转换思路(说实话,这里数位DP给了我一定的启发,虽然这题和数位DP没什么关系)

对于一个给定的区间[A,B],可以把A和B都表示成二进制的形式,例如:

  B:1010011

  A:1001001

然后从高位到低位开始查找,找到A与B第一个不同的位(在这里即第三位)。

随后把这个不同的位写成0,后面的所有位都写成1,这样就得到了[A,B]区间内二进制表示形式下1最多的那个数(此例中即为1001111)。

但是这样做还有一个需要特别注意的地方,就是当B的不同位后面都是1时,这个不同位是不需要换成0的(因为它保留为1仍在[A,B]区间内),例如:

  B:1011111

  A:1001001

这时含1最多的数就是1011111而不是1001111了。

代码很容易写出……

 

 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 int as[33],bs[33],cs[33];
 7 
 8 bool all_1(int x)
 9 {
10     for(int i=x;i>=1;i--)
11         if(bs[i]!=1)
12             return false;
13     return true;
14 }
15 
16 int main()
17 {
18     int t;
19 
20     scanf("%d",&t);
21 
22     while(t--)
23     {
24         int i;
25         long a,b;
26 
27         scanf("%ld %ld",&a,&b);
28         if(a>b)
29             a^=b^=a^=b;
30         for(i=1;a;++i)
31         {
32             as[i]=a&1;
33             a>>=1;
34         }
35         for(;i<=32;++i)
36             as[i]=0;
37         for(i=1;b;++i)
38         {
39             bs[i]=b&1;
40             b>>=1;
41         }
42         for(;i<=32;i++)
43             bs[i]=0;
44         for(i=32;as[i]==bs[i];i--)
45             cs[i]=as[i];
46         if(all_1(i-1))
47             for(;i>=1;i--)
48                 cs[i]=bs[i];
49         else
50         {
51             cs[i]=0;
52             for(--i;i>=1;i--)
53                 cs[i]=1;
54         }
55         int ans=0;
56         for(i=1;i<=32;i++)
57             if(cs[i]==1)
58                 ans++;
59         printf("%d\n",ans);
60     }
61 
62     return 0;
63 }
[C++]

 

posted @ 2013-07-12 22:19  ~~Snail~~  阅读(187)  评论(0编辑  收藏  举报