zoukankan      html  css  js  c++  java
  • POJ3252-Round Numbers 数学

    题目链接:http://poj.org/problem?id=3252

    题目大意:

      输入两个十进制正整数a和b,求闭区间 [a ,b] 内有多少个Round number

      所谓的Round Number就是把一个十进制数转换为一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number

      规定输入范围: 1<= a <b<=2E

    /*

    一开始错在计算组合数!!!正解是利用杨辉三角来算!!
    另外对于star=1的情况下也需要特判一下子
    思路是算出【0,star】和【0,fini】的round number(以下简称rn)个数,后者减去前者+1*【star是rn】(艾弗森约定)
    要计算【0,a】的rn个数,设a的二进制表示长度为lena,那么先打表f[]给出二进制表示数长度为1-->lena-1的这些数的rn。
    再计算长度为lena的,但是比a小的这些数里头有哪些是rn呢?
    计算同长度的rn的思路是:从高位到低位将a的二进制表示中的1(除最高位)逐次变为0,更低位的则在满足rn条件的前提下随便进行排列,得到的数一定是小于a的rn
    当然某一位变完了以后又会变回来的啊。这部分详见fun();

    */

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 using namespace std;
      6 #define MAX 35
      7 #define unsigned int long long
      8 long long f[MAX];
      9 long long  star,fini;
     10 char str0[35],str1[35];
     11 long long c[40][40];
     12 void   d2b(long long d, char *str)//十进制转成二进制!
     13 {
     14     int nStart = -1, i = 0;
     15     for (i=0; i<32; i++)
     16     {
     17         bool bOne = (0 != (d & (1 << (32-i-1) )));
     18         if (bOne && nStart < 0)
     19         {
     20             nStart = i;
     21         }
     22         if(nStart>=0)
     23         {
     24             str[i - nStart] = bOne ? '1' : '0';
     25         }
     26     }
     27     str[i - nStart] = '';
     28     return ;
     29 }
     30 
     31 long long pow3( long long a, long long b )//快速幂
     32 {
     33     long long r = 1, base = a;
     34     while( b != 0 )
     35     {
     36         if( b & 1 )
     37         r *= base;
     38         base *= base;
     39         b >>= 1;
     40     }
     41     return r;
     42 }
     43 
     44 void play_table(void)//计算组合数的!
     45 {
     46     for(int i=0;i<=35;i++)
     47         for(int j=0;j<=i;j++)
     48             if(!j || i==j)
     49                 c[i][j]=1;
     50             else
     51                 c[i][j]=c[i-1][j-1]+c[i-1][j];
     52     return;
     53 }
     54 
     55 void  Cf()//计算f[]
     56 {
     57     f[1]=1;
     58     for(int i=2;i<MAX;i++){
     59         int k=i/2;
     60         if(i%2)
     61             f[i]=(pow3(2,2*k)-c[2*k][k])/2;
     62         else
     63             f[i]=pow3(4,k-1);
     64     }
     65 }
     66 
     67 long long  fun(char ss[35])
     68 {
     69     int sum0=0;//ss中0的个数。
     70     int len=strlen(ss);
     71     long long ans=0;
     72     for(int i=1;i<len;i++)
     73         ans+=f[i];
     74     for(int k=1;k<len;k++)
     75     {
     76         if(ss[k]=='0')
     77             sum0++;
     78         else
     79         {
     80             int t0=ceil(1.0*len/2)-sum0-1;//至少需要的0个数
     81             int s=len-k-1;//剩下的可变位数
     82             if(t0<=0)
     83                 ans+=pow3(2,s);
     84             else
     85                 if(t0<=s)
     86                     for(int i=t0;i<=s;i++)
     87                         ans+=c[s][i];//(s,i);
     88         }
     89     }
     90     if(sum0>=ceil(1.0*len/2))//相当于本身
     91         ans++;
     92     return ans;
     93 }
     94 
     95 bool ok(char s[35])
     96 {
     97     int sum0=0;
     98     int len=strlen(s);
     99     if(strcmp(s,"1")==0)
    100         return 0;
    101     for(int i=1;i<len;i++)
    102         if(s[i]=='0')
    103             sum0++;
    104     if(sum0>=ceil(1.0*len/2))
    105         return 1;
    106     return 0;
    107 }
    108 
    109 int  main()
    110 {
    111     play_table();
    112     Cf();
    113     while(cin>>star>>fini)
    114     {
    115         d2b(star,str0);
    116         d2b(fini,str1);
    117         if(star==1) ans0++;//对1进行特判
    118         if(ok(str0))
    119             cout<<fun(str1)-fun(str0)+1<<endl;
    120         else
    121             cout<<fun(str1)-fun(str0)<<endl;
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    python 打印对象的所有属性值
    selenium+python测试
    java连接3种数据库 JdbcLinkDB --201801
    又来折腾--正则表达式
    Excel 将A表的基础数据拼接到B表中来-三种方法: ctrl+回车, VLOOKUP()函数,宏
    Excel如何快速统计一列中相同数值出现的个数--数据透视表
    Jmeter、Postman 、 loadrunner SoapUI 接口测试工具
    delphi 获取时间戳 如何得到 和 js 中 new Date().getTime();的 相同?
    IIS部署项目
    C#使用log4net记录日志
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/POJ3252-RoundNumbers.html
Copyright © 2011-2022 走看看