hdu 5491(位运算)

题意:给你n,a,b. 希望得到比n大,二进制1的个数在 a ,b之间的最小的数

思路:①满足条件,输出

           ②num < a 从右找到是0的最小位,变成1

           ③num > b从右到左找是1的最小位,加上一,即 n + 2 ^ i


 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <time.h>
typedef long long ll;
using namespace std;
int d[35];

int get(ll x)
{
    int all = 0,t = 0;
    while(x)
    {
        if(x & 1)
        {
            all ++;
            d[t++] = 1;
        }
        else
            d[t++] = 0;
        x >>= 1;
    }
    return all;
}

ll Pow(int x,int n)
{
    ll ans=1;
    while(n)
    {
        if(n%2)ans=ans*x;
        x=x*x;
        n=n/2;
    }
    return ans;
}

int main()
{
    int a,b,t,num;
    ll n;
    scanf("%d", &t);
    int Cas = 1;
    while(t--)
    {
        scanf("%I64d%d%d",&n,&a,&b);
        memset(d,0,sizeof(d));
        n++;
        num = get(n);
        while(1)
        {
            if(num >= a && num <= b)
            {
                printf("Case #%d: %I64d\n",Cas++,n);
                break;
            }
            else if(num < a)
            {
                int t = 0;
                while(d[t])
                    t++;
                d[t] = 1;
                n += Pow(2,t);
                num++;
            }
            else if(num > b)
            {
                int t = 0;
                while(!d[t])
                    t++;
                n += Pow(2,t);
                num = get(n);
            }
        }
    }
    return 0;
}

  


ps.我们需要的就是不停找借口让自己坚持下去

 


 

posted @ 2015-09-28 20:03  Przz  阅读(192)  评论(0编辑  收藏  举报