思路

先说一下个人思路,由于时间原因我把这题跳了:区间[0,b]中的RN-区间[0,a-1]中的RN就是区间[a,b]中的RN,求所有小于k的RN的个数,可以先找出二进制中k的每一个1,然后在这些1之后的几位数字中填入n个1和m个0(m>=n),那么这些组合数的结果相加就是小于k的RN个数,答案就能求出来了。

下面这份代码与上面无关,题解转载自林厚从的数学一本通,注释也给你们打好了。

代码

#include<bits/stdc++.h>
using namespace std;

int c[33][33]={0};
int bin[35]; //十进制n的二进制数

void play_table(){ //打表计算C(n,m)
    for(int i=0;i<=32;i++){
        for(int 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];
        }
    } 
    return;
} 

void dec_to_bin(int n){ //十进制n转换二进制,逆序存放到bin[]
    bin[0]=0; //b[0]是二进制数的长度
    while(n){
        bin[++bin[0]]=n%2;
        n/=2;
    }
}

int round(int n){ //计算比十进制数n小的所有RN数
    int i,j,sum=0; //sum存储比十进制数n小的所有RN数
    dec_to_bin(n); //计算长度小于bin[0]的所有二进制数中RN的个数
    for(i=1;i<bin[0]-1;i++){
        for(int j=i/2+1;j<=i;j++){
            sum+=c[i][j]; //计算长度等于bin[0]的所有二进制数中RN的个数
        }
    }
    int zero=0; //从高位向低位搜索过程中出现0的位的个数
    for(i=bin[0]-1;i>=1;i--){
        if(bin[i]){ //当前位为1
            for(j=(bin[0]+1)/2-(zero+1);j<=i-1;j++){
                sum+=c[i-1][j];
            }
        }else zero++;
    }
    return sum;
}

int main(){
    play_table();
    int a,b;
    cin>>a>>b;
    cout<<round(b+1)-round(a)<<endl;
    return 0;
}