zoukankan      html  css  js  c++  java
  • poj 3252 Round Numbers(数学)

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

    题意:一个数写成二进制,0不少于1就是round number,求给定区间内round number的个数。

    分析:显然第一步转化为0到n的round number个数。。设n写成二进制有len位,第一位取0时,后面只要满足0的个数要求就行了,不用考虑是否比n大。。可以先预处理一下长度不大于len的round number个数,记做t[len],t[len]=t[len-1]+∑C(len-1  k) , (k=0,1,...,len/2-1)。

    然后第一位取1时,往后是0的位只能取0,遇到第一个1时,再分情况考虑这一位为1和为0,然后考虑还需要多少位,往下递归即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=35;
     6 int C[maxn][maxn],sum[maxn][maxn][maxn],t[maxn];
     7 int start,finish;
     8 void CalC(){
     9     for(int i=1;i<maxn;i++)
    10         C[i][0]=C[i][i]=1;
    11     for(int i=2;i<maxn;i++){
    12         for(int j=1;j<i;j++){
    13             C[i][j]=C[i-1][j]+C[i-1][j-1];
    14         }
    15     }
    16     for(int i=0;i<maxn;i++){
    17         for(int s=0;s<=i;s++){
    18             sum[i][s][s]=C[i][s];
    19             for(int t=s+1;t<=i;t++){
    20                 sum[i][s][t]=sum[i][s][t-1]+C[i][t];
    21             }
    22         }
    23     }
    24 }
    25 void CalT(){
    26     t[1]=1;
    27     for(int i=2;i<maxn;i++){
    28         t[i]=t[i-1]+sum[i-1][0][(i-2)/2];
    29     }
    30 }
    31 int f(int n,int c,int len){
    32     if(c==0)return 1;
    33     if(c>=len)return n+1;
    34     int t=len-1;
    35     while(t>=0&&(n&(1<<(t-1)))==0){
    36         t--;
    37     }
    38     return f(n-(1<<(len-1)),c-1,t)+sum[len-1][0][c];
    39 }
    40 int solve(int n){
    41     if(n==0)return 1;
    42     int k=1<<30,len=31;
    43     while((k&n)==0){
    44         k>>=1;len--;
    45     }
    46     int l=len-1;
    47     while(l>=0&&(n&(1<<(l-1)))==0){
    48         l--;
    49     }
    50     return t[len-1]+f(n-(1<<(len-1)),(len-2)/2,l);
    51 }
    52 //bool Is_round(int n){
    53 //    int k=1,a=0,b=0;
    54 //    while(k<=n){
    55 //        if(k&n)a++;
    56 //        else b++;
    57 //        k<<=1;
    58 //    }
    59 //    if(a<=b)return true;
    60 //    return false;
    61 //}
    62 //int test(int n){
    63 //    int count=0;
    64 //    for(int i=1;i<=n;i++){
    65 //        if(Is_round(i))count++;
    66 //    }
    67 //    return count+1;
    68 //}
    69 int main(){
    70     CalC();
    71     CalT();
    72     int n;
    73 //    while(cin>>n){
    74 //        cout<<solve(n)<<' '<<test(n)<<endl;
    75 //    }
    76     cin>>start>>finish;
    77     cout<<solve(finish)-solve(start-1)<<endl;
    78     return 0;
    79 }
  • 相关阅读:
    你真的理解正则修饰符吗?
    一个简单易用的容器管理平台-Humpback
    【译】参考手册-React组件
    【译】快速起步-组件与属性
    css可应用的渐进增强新特性
    javascript编程杂记
    ES6模块的import和export用法总结
    对于未来chrome80 samesite问题的兼容解决方案
    mogodb数据库简单的权限分配
    egg.js npm start 启动报错
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7282581.html
Copyright © 2011-2022 走看看