思路
先说一下个人思路,由于时间原因我把这题跳了:区间[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;
} 
京公网安备 11010502036488号