神殿

                                            问题 F: 神殿

题目描述

icebound通过勤工俭学,攒了一小笔钱,于是他决定出国旅游。这天,icebound走进了一个神秘的神殿。神殿由八位守护者守卫,总共由64个门组成,每一道门后都有一个迷宫,迷宫的大小均为100 × 100。icebound在迷宫中总共耗时T小时,消耗食物K公斤。历经千辛万苦之后,icebound终于穿越了迷宫,到达了神殿的中心。神殿的中心有一个宝箱。宝箱上显示有两个正整数lr。icebound苦思冥想,终于发现一些打开宝箱的线索。你需要找到一个数P,它具有一个美妙的性质:它是[l, r]中所有数的二进制表示里,1的个数最多的一个数。如果你发现了这个美妙的数字,你就可以打开宝箱,获得巨额财富。
比如[4, 8]中:
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000
二进制表示中1的个数最多的数是7,它含有31

输入

输入一行,两个正整数:lr,用空格隔开,代表神殿中宝箱上显示的数。
1 ≤ T < 231,1 ≤ K ≤ 105,1 ≤ l ≤ r ≤ 2 × 109

输出

一个十进制数P,代表满足条件的解。如果有多个P满足条件,输出最小的P

样例输入 Copy

4 8

样例输出 Copy

7

题意:找出L 到 R这个区间内的数的二进制表示形式下 1 的个数最多的数。

思路:先把 L 和 R 表示成二进制,求出二进制表示形式下的长度l1,l2,R全都是1或者L=R,直接输出R,如果l1<l2, 退而求其次,让l2-1, 这就是1的个数,转换成十进制输出即可,如果长度相同,则从高位开始比较,如果出现不同的,让l1不同位后面的全部为1 即可,转换成二进制输出,代码如下:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#define LL long long
#define inf 0x3f3f3f3f
#include<algorithm>
using namespace std;
int a[50],b[50];
int solve(int c[],LL x)
{
    int i=0;
    while(x)
    {
        c[i++]=(int)(x%2);
        x=x/2;
    }
    return i;
}
int main()
{
    int l,r;
    cin>>l>>r;
    int l1=solve(a,l);
    int l2=solve(b,r);
    if(l==r)
    {
        printf("%l0ld\n",l);
        return 0;
    }
    int flag=0;
    for(int i=0; i<l2; i++)     //倒着来
    {
        if(!b[i])
        {
            flag=1;
            break;
        }
    }
    if(!flag)
    {
        printf("%lld\n",r);
        return 0;
    }
    LL x=0;
    if(l1==l2)
    {
        for(int i=l1-1; i>=0; i--)
        {
            if(a[i]<b[i])          //0 1
            {
                x=x*2;
                for(int j=i-1; j>=0; j--)
                    x=x*2+1;
                break;
            }
            else x=x*2+a[i];      //1 0
        }
    }
    else
    {
        for(int i=1; i<l2; i++)  //退而求其次
            x=x*2+1;
    }
    printf("%lld\n",x);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值