POJ 3252 组合计数

Round Numbers

Time Limit: 2000MS Memory Limit: 65536K

Total Submissions: 9149 Accepted: 3248

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

/******************************
    author   : Grant Yuan
    time     : 2014/10/16 17:37
    algorithm: 组合计数
    source   : POJ 3252
    explain  : 按照G++交的,C++会跪
*******************************/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int a[35],len;
int sum[40][40];
void slove(int num)
{
    a[0]=0;len=0;
    while(num){
        a[++len]=num&1;
        num=num>>1;
    }
}
void Cal_sum()
{
    memset(sum,0,sizeof(sum));
    for(int i=0;i<=32;i++)
        for(int j=0;j<=i;j++)
    {
        if(j==0||i==j) sum[i][j]=1;
        else sum[i][j]=sum[i-1][j]+sum[i-1][j-1];
    }
}
int Get_sum1()
{
    int l=len,res=0;
    for(int i=1;i<len-1;i++)
    {
        for(int j=i/2+1;j<=i;j++)
        {
            res+=sum[i][j];
        }
    }
    return res;
}
int Get_sum2()
{
    int res=0,zero=0;
    for(int i=len-1;i>=1;i--)
    {
        if(a[i]){
            for(int j=(len+1)/2-zero-1;j<i;j++)
                res+=sum[i-1][j];
        }
        else zero++;
    }
    return res;
}
int main()
{
    int ans1,ans2,s,f;
    Cal_sum();
    while(~scanf("%d%d",&s,&f)){
        ans1=0;ans2=0;
        slove(s);
        ans1+=Get_sum1();ans1+=Get_sum2();
        slove(f+1);
        ans2+=Get_sum1();ans2+=Get_sum2();
        printf("%d %d\n",ans1,ans2);
        printf("%d\n",ans2-ans1);
    }
    return 0;
}
时间: 2024-12-24 23:10:11

POJ 3252 组合计数的相关文章

POJ 1496 POJ 1850 组合计数

Code Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8256 Accepted: 3906 Description Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is t

POJ 1019 组合计数

链接:POJ 1019 /***************************************** author : Grant Yuan time : 2014/10/19 14:38 source : POJ 1019 algorithm: 组合计数 ******************************************/ #include <iostream> #include <cstdio> #include <algorithm> #

poj 3088 组合计数,第二类斯特林数

题意:给出n个数字[1,n],问你可以组成多少种不同的序列,其中每一个序列由几个部分组成,每个部分包含几个数字,每部分内数字无序,部分之间数字有序.每个数字最多使用一次,可以不用. 思路:枚举从n个数字中选出i个数字(组合数),再枚举将这i个数字分成j个部分(第二类斯特林数),然后乘上j的全排列. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5

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

poj 3252 Round Numbers(数位DP)

Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11003   Accepted: 4064 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',

Yue Fei&#39;s Battle(组合计数递推)

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3 // 非常完美的分析,学到了,就是要细细推,并且写的时候要细心 还有除法取模需要用逆元 #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> using namespace std; #define MOD 1000000007 #define L

bzoj 1004 Cards 组合计数

这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二元组(a,p),a∈A,p∈P ,使得p(a)=a,即a在置换p的作用后还是a). Polya定理其实就是告诉了我们一类问题的不动点数的计算方法. 对于Burnside定理的考察,我见过的有以下几种形式(但归根结底还是计算不动点数): 1.限制a(a∈A)的特点,本题即是如此(限制了各颜色个数,可以

HDU4675-GCD of Sequence(数论+组合计数)

GCD of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 949    Accepted Submission(s): 284 Problem Description Alice is playing a game with Bob. Alice shows N integers a1, a2, -, aN, an

poj 3252 Round Numbers (组合数学)

链接 :poj 3252 题意:一个数转化成二进制之后,0的个数大于等于1的为round数, 给定一个区间[m,n],问这区间内有多少round数 分析:要求[m,n]间的的round数, 可以用[1,n+1)的个数减去[1,m)的个数, 对于比N小的round数的个数: 化为二进制的长度比N的长度小的数:如果长度为L,那么高位肯定是1, 然后枚举0的个数,利用组合数求即可 长度和N相等但比N小的数: 从高位开始枚举,若出现1,则将这位看作0,再枚举之后的低位,肯定是比原数小的 依次下去,注意统