poj3252--Round Numbers(组合篇1--求1到n内的二进制数中0的个数大于1的个数)

Round Numbers

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 9525   Accepted: 3420

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone‘ (also known as ‘Rock, Paper, Scissors‘, ‘Ro, Sham, Bo‘, and a host of other names) in order to make arbitrary decisions such as who gets to be milked first.
They can‘t even flip a coin because it‘s so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,

otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of
N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones,
it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤
Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively
Start
and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range
Start..Finish

Sample Input

2 12

Sample Output

6

Source

USACO 2006 November Silver

题意:给出n到m求n到m内的有多少Round数,转化为二进制后0的个数大于等于1到个数。

转化为计算1到n,1到m的个数,再相减

将一个数x转化为二进制数,那么这个数的最高位一定是1,记录位数cnt,

1、从低位开始直到cnt-1,计算第i位为1,i位之前全部为0时的个数。

2、计算第cnt位时,从高位向低位遍历,当第i位为1时,累加该位为0时的种数。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
LL c[33][33] ;
int digit[40] , cnt ;
void get_c()
{
    LL i , j ;
    memset(c,0,sizeof(c)) ;
    c[0][0] = 1 ;
    for(i = 1 ; i < 33 ; i++)
    {
        c[i][0] = 1 ;
        for(j = 1 ; j < i ; j++)
            c[i][j] = c[i-1][j-1] + c[i-1][j] ;
        c[i][j] = 1 ;
    }
    return ;
}
LL solve(LL temp)
{
    LL ans = 0 , i , j , num0 , num1 , k = 0 ;
    memset(digit,0,sizeof(digit)) ;
    cnt = 0 ;
    while( temp )
    {
        digit[++cnt] = temp%2 ;
        if( k == 0 && digit[cnt] == 1 )
            k = cnt ;
        temp /= 2 ;
    }
    for(i = 1 ; i < cnt ; i++)
    {
        //当前位放1
        num0 = 0 ;
        num1 = 1 ;
        for(j = 0 ; j < i ; j++)
        {
            if( num1+j > (i-1-j)+num0 ) break ;
            ans += c[i-1][j] ;
        }
    }
    num0 = 0 ;
    num1 = 1 ;
    for(j = i-1 ; j > 0 ; j--)
    {
        if( digit[j] == 0 )//如果这位是0
        {
            num0++ ;
            continue ;
        }
        //这位是1,先累加放0的,再放1
        num0++ ;
        for(k = 0 ; k < j ; k++)
        {
            if( num1+k > (j-1-k)+num0 ) break ;
            ans += c[j-1][k] ;
        }
        num0-- ;
        num1++ ;
    }
    if( num0 >= num1 ) ans++ ;
    return ans ;
}
int main()
{
    LL n , m ;
    get_c() ;
    while( scanf("%I64d %I64d", &n, &m) != EOF )
    {
        printf("%I64d\n", solve(m)-solve(n-1)) ;
    }
    return 0;
}

时间: 2024-09-30 04:17:17

poj3252--Round Numbers(组合篇1--求1到n内的二进制数中0的个数大于1的个数)的相关文章

POJ-3252——Round Numbers

POJ-3252——Round Numbers 传送门:http://poj.org/problem?id=3252 题意:求n-m中二进制表示0的数量不小于1的数的个数 要找二进制0和1的个数,因为是按位数来找的,可以考虑数位dp 状态dp[pos][_0][_1] 表示为dp[当前第几位][含0的个数][含1的个数] 这个题注意dfs传参的时候要多传进去一个lead(是否是前导0)因为此时前导0的存在会影响最终的答案 之前的数位dp都是在十进制的基础上dp,而本题是二进制,拆分的时候拆成二进

poj3252 Round Numbers

Round Numbers POJ - 3252 题目大意: 输入两个十进制正整数a和b,求闭区间[a,b]内有多少个Round Number? 所谓的Round Number就是一个把十进制数转换成一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number. 注意 转换所得的二进制数,最高位必然是1,最高位前不允许有0 /* 以前用的组合数学,听说dalao也用数位dp做,我也来一下 */ #include<iostream> #include<c

POJ-3252 Round Numbers (数位DP)

Round Numbers http://poj.org/problem?id=3252 Time Limit: 2000MS   Memory Limit: 65536K       Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro,

POJ3252 Round Numbers 组合数学||数位DP

这题目做了两个小时,调试的头都晕了... 题型是数位DP中很常见的,给一个区间[l,r]求区间[l,r]中的 符合题目要求的数的个数,本题求的 是 区间中 的数  它的二进制中0的个数大于等于1的个数的    这些数的个数,不好意思表达能力有点差...例如[1,4]答案是2, 因为 2的二进制是10,0的个数大于等于1的个数,4的二进制是100,0的个数大于1的个数,所以答案是两个 好了第一反应肯定是 设定一个函数 f(r) - f[l - 1]就是答案,那么显然这个函数f(r)的意思就是 1

POJ 3252- Round Numbers(求区间中二进制数中0个数大于1的数的总数)

Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10008   Accepted: 3628 Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors',

POJ3252 Round Numbers 题解 数位DP

题目大意: 求区间 \([x,y]\) 范围内有多少数的二进制表示中的'0'的个数 \(\ge\) '1'的个数. 解题思路: 使用 数位DP 解决这个问题. 我们设状态 f[pos][num0][num1][all0] 表示在: 当前所在数位为 pos : 当前选择的'0'的个数为 num0: 当前选择的'1'的个数为 num1: 到当前位位置是不是前面的数都是前导零(如果都是前导0则 all0==true,否则 all==false). 下的方案数. 我们开函数 dfs(int pos, i

POJ 3252 Round Numbers

Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12824   Accepted: 4946 Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors',

poj 3252 Round Numbers 【推导&#183;排列组合】

以sample为例子 [2,12]区间的RoundNumbers(简称RN)个数:Rn[2,12]=Rn[0,12]-Rn[0,1] 即:Rn[start,finish]=Rn[0,finish]-Rn[0,start-1] 所以关键是给定一个X,求出Rn[0,X] 现在假设X=10100100  这个X的二进制总共是8位,任何一个小于8位的二进制都小于X 第一部分,求出长度为[0,7]区间内的二进制是RoundNumber的个数  对于一个长度为Len的二进制(最高位为1),如何求出他的Rou

poj3252(Round Numbers)

题目地址:Round Numbers 题目大意: “Round Numbers” 是一个十进制的数转化为二进制,如果在二进制中 “0”的个数不小于“1”的个数,就称为“Round Numbers” .本题求出n到m区间(闭区间)的“Round Numbers” 有多少个. 解题思路: 排列组合的公式:C(n,m)=C(n-1,m-1)+C(n,m-1). (转)   比如:    22 =  10110b  如果要求 <=22的Round Numbers,也就是找出1-22有多少个二进制的0不少