POJ 3252 Round Numbers

  简单的组合数学。

  题意:给出两个数,找出这两个数之间的Round Numbers。范围包括这两个数。

  所谓的Round Numbers就是将给出的十进制数转化成二进制之后,0的个数 >= 1的个数。

  思路:

  设给出的数为m,其二进制长度为len。

  先找出长度小于 len 的情况,这一种情况比较简单。

  另一种就是寻找和 m 的长度相同且 <= m的情况。

  从高位到地位枚举m的为1的位置,设为site。

  计算site之前的0和1 的个数差  记为 lead,然后计算出site之后最少可以有几个0,剩下的就是组合数的累加了。

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 
 6 #define LL unsigned long long
 7 #define Max(a,b) (a > b ? a : b)
 8 
 9 using namespace std;
10 
11 LL bin[60],cn[50][50];
12 
13 LL cal(LL m)
14 {
15 
16     int i,j,len,lead;
17 
18     i = 1;
19 
20     while(m > 0)
21     {
22         bin[i++] = m%2;
23         m /= 2;
24     }
25 
26     len = i-1;
27 
28     LL ans = 0;
29 
30     for(i = 1;i < len; ++i)//统计比m短的情况
31     {
32         for(j = (i+1)/2;j < i; ++j)//j代表0的个数
33         {
34             ans += cn[j][i-1];
35         }
36     }
37 
38     for(lead = 1,i = len-1;i >= 1;i--)//lead统计 sum(1) - sum(0)
39     {
40         if(bin[i] == 1)
41         {
42             for(j = Max(0,(i + lead - 1)/2);j < i; ++j)//j代表0的个数
43             {
44                 ans += cn[j][i-1];
45             }
46             ++lead;
47         }
48         else
49         {
50             --lead;
51         }
52     }
53 
54     if(lead <= 0 && bin[1])
55         ans += 2;
56     else if(lead <= 0)
57         ++ans;
58     else if(lead == 1 && bin[1] && len != 1)
59         ans += 1;
60 
61     return ans;
62 }
63 
64 void init()//c(n,m) = c(n-1,m-1) + c(n,m-1); 从m中选n
65 {
66     int i,j;
67     cn[0][0] = 0;
68     for(i = 1;i <= 32; ++i)
69     {
70         for(j = 0;j <= i; j++)
71         {
72             if(j == 1)
73                 cn[j][i] = i;
74             else if(j == 0 || i == j)
75                 cn[j][i] = 1;
76             else
77                 cn[j][i] = cn[j-1][i-1] + cn[j][i-1];
78         }
79     }
80 }
81 
82 int main()
83 {
84 
85     LL l,r;
86 
87     init();
88 
89     while(cin>>l>>r)
90     {
91 
92         l = cal(l-1);
93 
94         r = cal(r);
95 
96         cout<<r-l<<endl;
97     }
98     return 0;
99 }
View Code

 

posted @ 2013-09-07 19:54  好小孩  阅读(167)  评论(0编辑  收藏  举报