码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5491 The Next (位运算)

时间:2015-09-30 19:30:26      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

 http://acm.hdu.edu.cn/showproblem.php?pid=5491

 

题目大意:给定一个数D,它的二进制数中1的个数为L,求比D大的数的最小值x且x的二进制数中1的个数num满足s1 <= num <= s2
 
分析:将D+1变成n,求其二进制数中1的个数L
 
(1)如果L在(s1, s2)范围内,直接输出
 
(2)如果num<s1,从右到左找0的最小位i,将该位的0改成1(即:1的个数少了,增加一个1),n的值则增加2^i(即:n += 2^i)
 
 (3) 如果num>s2,从右到左找1的最小位i,将该位+1(即:1的个数多了,需要减少1),n的值则增加2^i(即: n += 2^i)
 
 从左到右找是为了保证n值最小增加
 
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>

const int N = 110;
typedef long long ll;

using namespace std;

int d[N];

int get(ll n)
{
    int j = 0, num = 0;
    while(n)
    {
        d[j++] = n % 2;
        if(n % 2 == 1)
            num++;
        n /= 2;
    }
    return num;
}//求n的二进制中1的个数

ll Pow(int a, int b)
{
    ll ans = 1;
    while(b)
    {
        if(b % 2 == 1)
            ans *= a;
        a *= a;
        b /= 2;
    }
    return ans;
}//快数幂求a的b次幂

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

 

hdu 5491 The Next (位运算)

标签:

原文地址:http://www.cnblogs.com/qq2424260747/p/4849839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!