题目描述
如果一个正整数的二进制表示中,每个比特(00 或 11)的左边或右边都至少有一个相同的比特,Dr. X 就认为它是一个“幸运数字”。例如:
-
(1)2=(1)10(1)2=(1)10 有落单的 11,它不是幸运数字。
-
(110111)2=(55)10(110111)2=(55)10 有落单的 00,它不是幸运数字。
-
(111110011)2=(499)10(111110011)2=(499)10 是幸运数字。
-
(110011001100)2=(3276)10(110011001100)2=(3276)10 是幸运数字。
对于给定的 a 和 b,Dr. X 希望你求出 a,a+1,a+2,…,,a+1,a+2,…,b 中幸运数字的数量。
输入格式
输入空格分隔的整数 a 和 b。
输出格式
输出一行一个整数,代表 a 和 b 之间幸运数字的数量。
输入输出样例
输入 #1复制
1 100
输出 #1复制
14
输入 #2复制
4096 65535
输出 #2复制
1364
分析:很明显是枚举的题目,那么我们应该优化枚举过程,但是基于水平有限,未能找到,况且题解过程是借鉴的过程。
做法:第一步即是分析基本步骤,经过分析可以知道,此题分为进制转化和对枚举过程的判断。
进制转换
方法一
利用了binary函数
bitset<32> binary(i);
string a = binary.to_string();
我的思路是二进制没有0开头的,所以可以根据循环抹零(具体还没找到方法)
方法二
直接通俗的进制转换成字符串的形式
string s="";//先定义为空的字符串,方便后续加入
int sa=i;//当前10进制的数
while(sa>0){
if(sa%2==0){
s+='0';
}else{
s+='1';
}
sa/=2;
}这里即完成了进制转换
//此时的s 就囊括了二进制字符 ,转进制成功
bool flag=true;
for(int j=0;j<s.size();j++){
if(s[j]!=s[j-1]&&s[j]!=s[j+1]){//不满足的条件
flag=false;
break;
}
}
if(flag){
sum=sum+1;
}
即完成了枚举情况的判断。
所有代码实现
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, k, sum = 0; // 表示起始位置和终点位置,sum 记录满足情况 8
cin >> n >> k;
for (int i = n; i <= k; i++) { // 枚举所有情
string s="";
int sa=i;//不能改变遍历的值,所以用另一个变量取代
while(sa>0){//进制转换
if(sa%2==0) {
s+='0';}//通过加字符串的形式
else {
s+='1';
}
sa/=2;
}
//此时的s 就囊括了二进制字符 ,转进制成功
bool flag=true;
for(int j=0;j<s.size();j++){
if(s[j]!=s[j-1]&&s[j]!=s[j+1]){//不满足的条件出生
flag=false;
break;
}
}
if(flag){
sum=sum+1;
}
}
cout<<sum;
return 0;
}
以上就是基本题解,有借鉴。