• poj 3252 Round Numbers


    题解:使用排列组合的知识解决!!!

    主要求1-n之间的Round Numbers,然后减下就可以了,现在主要就是怎样求n以内的Round Numbers数。

    分2部分求:

    1.计算出n的2进制位数为m,这1-(m-1)之间的数可以很快求出,

    当为偶数2k的时候:C(2k-1,k)+C(2k-1,k+1)+……+C(2k-1,2k-1)=2^(2k-2);

    当为奇数2k+1的时候:C(2k,k+1)+C(2k,k+2)+……+C(2k,2k)=2^(2k-1)-1/2*C(2k,k);

    2.再就是求m个2进制位时的Round Numbers数。由于第一个数一定是1所以不变然后继续向低位扫描,并计数0的个数,

    当扫描到i位时是1,算出后面至少需要k个0,则不大于n且是Round Numbers的个数为C(i,k)+C(i,k+1)+……+C(i,i);

    直到扫描结束。最后还需判断n本身满足不!!!

    代码如下:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<iomanip>
     5 #include<cmath>
     6 #include<cstring>
     7 #include<vector>
     8 #define ll __int64
     9 #define pi acos(-1.0)
    10 #define MAX 50000
    11 using namespace std;
    12 int c[100],a[33],num1,num0,cm[32][32];
    13 int pows(int b)
    14 {
    15     return 1<<b;
    16 }
    17 int C(int n){
    18     int ans=pows(n-2);
    19     if (n&1)
    20         ans -= cm[n-1][(n-1)/2]/2;
    21     return ans;
    22 }
    23 void init(){
    24     int i,j;
    25     for (i=0;i<31;i++) cm[i][0]=1,cm[i][i]=1;
    26     for (i=2;i<31;i++)
    27         for (j=1;j<i;j++)
    28             cm[i][j] = cm[i-1][j]+cm[i-1][j-1];
    29     c[0]=c[1] = 1;
    30     for (i=2;i<31;i++){
    31         c[i] = C(i)+c[i-1] ;
    32     }
    33 }
    34 int binum(int n){
    35     int num=0;
    36     num1=0;
    37     while (n){
    38         a[num++] = n%2;
    39         num1 += n%2;
    40         n/=2;
    41     }
    42     return num;
    43 }
    44 int fun(int n){
    45     int ans = 0,i0=0,j,k;
    46     int num = binum(n);
    47     num0 = num - num1;
    48     ans = c[num-1];
    49     j=(num+1)/2;
    50     if (num0>=num1) ans++;
    51     if (num!=1)
    52         for (int i=num-2;i>=0;i--){
    53             if (a[i]){
    54                 if(i0+1>=j) ans += pows(i);
    55                 else
    56                     for (k=j-i0-1;k<=i;k++){
    57                         ans += cm[i][k];
    58                     }
    59             }
    60             else i0++;
    61         }
    62     return ans;
    63 }
    64 int main(){
    65     init();
    66     int n,m;
    67     scanf("%d%d",&n,&m);
    68     printf("%d
    ",fun(m)-fun(n-1));
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    cdoj793-A Linear Algebra Problem
    C语言各种数据类型取值范围
    taro 在components文件夹中 新建组件时,组件支持自定义命名,但是不能大写开头
    taro 不支持render中,使用函数多条件渲染
    taro 引用相对路径图片
    taro CSS Modules 的使用
    taro refs引用
    taro 环境判断
    input 禁止 复制 粘贴 剪切 操作
    windows 系统中 use arrow keys怎么操作?
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3221113.html
Copyright © 2020-2023  润新知