给定一个范围[a,b] (0<=a<b<=10^18) 求出该范围内二进制中1的个数最多的数,如果存在多个答案,输出最小的那个数
标签:
给定一个范围[a,b] (0<=a<b<=10^18) 求出该范围内二进制中1的个数最多的数,如果存在多个答案,输出最小的那个数
输入数据有多组,每组数据输入两个整数a,b,表示区间[a, b]。
输出该区间内二进制的1最多的整数,如果有多个数二进制1的个数相同,输出最小的那个数。
4 8 7 14
7 7
思路:
区间[a,b],如果a==b,输出a, 先把a,b化为二进制数,每位分别保存到数组中,如果a的二进制位数小于b的位数,那么直接输出 2^(b的位数-1) -1(此处如果b等于 2^b的位数 -1 就直接输出b) ,也就是二进制数比b少一位且所有位均为1,如果a的位数等于b的位数,要求最小的符合题意的数,尝试着从a的二进制低位开始,如果是0,将其变为1,看是否小于等于b,如果是,继续操作,如果不是,退出。
#include<iostream> #include<cstdio> using namespace std; #define ll long long ll n,m; int nn[65],mm[65]; ll p[65]; void inti() { p[0]=1; for(int i=1;i<63;i++)p[i]=p[i-1]<<1; } int getbit(ll x,int a[]) { int s=0; while(x) { a[s++]=x%2; x/=2; } return s; } int main() { inti(); while(~scanf("%lld%lld",&n,&m)) { int lenn=getbit(n,nn); int lenm=getbit(m,mm); if(lenn<lenm){// input 3 7 output 7 if(m==p[lenm]-1)printf("%lld\n",m); else printf("%lld\n",p[lenm-1]-1); continue; } // printf("lenn=%d\n",lenn); for(int i=0;i<lenn;i++) { if(nn[i]==0) { //printf("** %lld %d\n",n,i); if(n+p[i]<=m)n+=p[i]; else break; } } printf("%lld\n",n); } return 0; }
标签:
原文地址:http://www.cnblogs.com/kylehz/p/4324812.html