poj 3252 Round Numbers

本文介绍了一种算法,用于解决在指定范围内找出二进制表示中0的数量大于等于1的数量的问题。通过计算二进制位数并进行组合排序,最终得出解。文章提供了一个C++实现示例。

这个题就是要你找在区间[l,r]之中有多到少个二进制数0的个数大于等于1的个数(没有前导0)

我的解题思路是:

先求出这个数有多少位n;然后进行组合排序:

 

排序要分两种情况:

第一种:就是位数小于n,我们假设要对m个数进行0与1的组合排序,那么m+1位一定是1;那么我们就只要举例到1~n-2位。

第二种:就是n位,第一位我们不管一定为1,那么我们就列举后面出现1的情况,如果为1,那么我们就把该位设为0,假设该位为m,那么m前面已经有k个0,那么到m位就有k+1个0了;

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#include<string>
#define LL long long
using namespace std;
int c[33][33];
void Get_c( )
{
    for( int i = 0 ; i < 33 ; i ++ ){
         for( int j = 0 ; j <= i ; j ++ ){
              if( j == 0 || j == i )
                  c[i][j] = 1;
              else c[i][j] = c[i-1][j] + c[i-1][j-1];
        }    
    }
}
LL Solve( int n ){
  LL sum = 0;
  int len = 0,N=n;
  while( N ){
           len ++;
           N >>=1;
        }
  for( int i = 1; i < len -1 ; i ++ ){
       for( int j =  (i>>1) +1 ; j <= i  ; j ++ ){           
            sum += c[i][j]; 
       }
  }  
  int zero = 0;
  for( int i = len - 2  ; i >= 0 ; i -- ){
       if( ( n >> i )&1 == 1 ){
               for( int j = (( len + 1 )>>1) - zero - 1; j <= i ; j ++ ){
                  sum += c[i][j];
            }
       }
       else zero++;
  }
  return sum;
}
int main(  ){
    int l,r;
    Get_c( );
    while( scanf( "%d %d",&l,&r )==2 ){
          printf( "%I64d\n",Solve( r + 1 ) - Solve( l  ) );    
    }
    //system( "pause" );
    return 0;
}

转载于:https://www.cnblogs.com/bo-tao/archive/2012/08/10/2631499.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值