题目链接:点击打开链接
题意:A代表一到多个1,B代表一到多个0,组成二进制不长于63位的数字。形式为ABAB...A或ABABAB...AB;
分析:一个令我印象深刻的位运算题目,同时巩固了对set使用的熟练程度,第一次使用unsigned long long着实不适应;
思路详见代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#define ull unsigned long long
using namespace std;
char str[100];
ull n,m;
set<ull> ss;
void init()
{
int index=0;
for(int i=1;i<64;i++)
{
for(int j=0;j<63;j++)
{
if(i+j<=63) //暴力所有长度小于63的情况一共2015种
{
int cnt=i;
ull A=1ull;//初始化注意事项加ull
for(int k=1;k<i;k++)
{
A=A<<1;
A++;
}
ss.insert(A);
ull sta=A;
while(cnt<=63)//位运算一定用位数来判停,最多循环32次,复杂度2015*32,1000ms足够,况且是打表
{
sta=sta<<j;
cnt+=j;
if(cnt>63) break;
ss.insert(sta);
sta=sta<<i;
sta+=A;
cnt+=i;
if(cnt>63) break;
ss.insert(sta);
}
}
}
}
}
void cal()
{
int ans;
set<ull>::iterator it;
for(it = ss.begin() ; it != ss.end() ; ++it)
{
if(*it>=n && *it<=m)
ans++;
}
printf("%d\n",ans);
}
int main()
{
init();
// printf("%d\n",ss.size()); 一共4809个符合情况的,直接遍历即可。
while(~scanf("%llu%llu",&n,&m))
{
cal();
}
return 0;
}