POJ 3252 Round Numbers

这是一个数学题。

这就是我一开始给他的定义。

题目中的故事都是无关的,题目要求如下:

给出Round Number定义,给出Start,Finish两个数。求在[Start ,Finish]这个区间内的Round Number 有多少个。

其中Round Number是这样定义的:将当前数其转化为二进制,如果0的个数大于等于1的个数,当前数就是Round Number。

思路:

1、求[Start ,Finish]这个区间的Round Number 的数量可以转化为求[0,Start -1]和[0,Finish]这两个区间中Round Number的数量,然后相减得出。

2、然后对于每一个某个数到0的区间来说,可以针对这个数来处理出共有多少个Round  Number。这就是一个函数就可以解决的问题了。

3、对于这个函数来说,处理的这个数要先转换成二进制存贮。具体方法看自己,什么方法用的顺手用什么方法。

我们假设转化成二进制后长度为6,我们要分两部分来处理。

(1)、第一部分是0到五位,需要枚举位数处理。

对于五位长的数来说,第一位只能是1,剩下四位可以取四个0、三个0才能是Round Number,两个0就不行了。也就是说需要加C(4,4),C(4,3).

对于四位长的数来说,第一位只能是1,剩下的三位可以取三个0,两个0。一个0就不行了。也就是说需要加C(3,3),C(3,2).

以此类推,直到计算完成为止。

(2)、第二部分是当六位数的时候。

第一位一定是1是不能改变的,后面跟着的连续的几个零也是不能改变的。所以只能在第二个1开始处理。

将每一次遇到的1视为0,计算从第一位到当前位共有多少个1多少个0,然后计算此位之后有多少个1,多少个0就能构成Round Number,用组合数计算。

注意:如果当前数转化为二进制后发现为Round Number,计数器需要加一。


下面是我的代码:

#include <stdio.h>
int c[35][35]= {0},len=0;
char s[35];
int po(int a,int b) //平方函数
{
    int sum=1;
    while(b>0)
    {
        sum*=a;
        b--;
    }
    return sum;
}
int Rn(int num)  //计算从0到x的round number 的个数
{
    if(!num)
    {
        return 0;
    }
    len=0;
    int cnt=0,One=0,Zero=0;
    while(num)//处理成二进制
    {
        s[len]=(num%2)+'0';
        if(s[len]=='1')
        {
            One++;
        }
        else
        {
            Zero++;
        }
        num/=2;
        len++;
    }
    if(Zero>=One)//如果当前数为Round  Number  则计数器加一
    {
        cnt++;
    }
    for (int i = 1; i < len - 1; i++)
    {
        for (int j = i / 2 + 1; j <= i; j++)
        {
            cnt += c[i][j];
        }
    }
    int i=len-1;
    One =1;
    Zero=0;
    while(i>0)
    {
        while(s[i-1]!='1'&&i>0)
        {
            Zero++;
            i--;
        }
        if(i<=0)
        {
            break;
        }
        for(int j=(len+1)/2-(Zero+1); j<=i-1; j++)
        {
            cnt+=c[i-1][j];
        }
        One++;
        i--;
    }
    return cnt;
}
void S()//C(n,m)初始化
{
    int i,j;
    for(i=0; i<33; i++)
    {
        for(j=0; j<=i; j++)
        {
            if(!j||i==j)
            {
                c[i][j]=1;
            }
            else
            {
                c[i][j]=c[i-1][j-1]+c[i-1][j];
            }
        }
    }
}
int main()
{
    int a,b;
    S();
    while(~scanf("%d%d",&a,&b))
    {
        printf("%d\n",Rn(b)-Rn(a-1));
    }
    return 0;
}


posted @ 2013-12-22 10:17  、小呆  阅读(152)  评论(0编辑  收藏  举报