hdu 5491

本文介绍了一种算法,用于解决在给定的二进制数范围内找到满足特定条件的最小值的问题。通过逐步修改原始数值,算法确保了输出值既大于原始数,又满足指定的1的个数范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The Next

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 594 Accepted Submission(s): 232

Problem Description
Let L denote the number of 1s in integer D’s binary representation. Given two integers S1 and S2, we call D a WYH number if S1≤L≤S2.
With a given D, we would like to find the next WYH number Y, which is JUST larger than D. In other words, Y is the smallest WYH number among the numbers larger than D. Please write a program to solve this problem.

Input
The first line of input contains a number T indicating the number of test cases (T≤300000).
Each test case consists of three integers D, S1, and S2, as described above. It is guaranteed that 0≤D<231 and D is a WYH number.

Output
For each test case, output a single line consisting of “Case #X: Y”. X is the test case number starting from 1. Y is the next WYH number.

Sample Input
3
11 2 4
22 3 3
15 2 5

Sample Output
Case #1: 12
Case #2: 25
Case #3: 17

Source
2015 ACM/ICPC Asia Regional Hefei Online

刚开始竟然傻傻地以为这道题主要考验快速统计二进制数中1的个数,费尽心思用了各种高效率函数都没水过,后来仔细想想如果每次都++再去统计也太慢了,如果输出结果和原数相差比较大的话,是铁定要超时的。
因为是要求1的个数满足一定的要求,所以从这方面下手,因为是要输出满足条件的最小值,所以每次都从二进制的最小位开始变。1的个数不够就去0添1,1的个数多就找最小位的1进位。然后再统计是否满足条件,重复上述步骤直到满足条件输出。

#include<iostream>
#include<stdio.h>
using namespace std;


int BitCount(unsigned int n)
{
    unsigned int table[256] =
    {
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
    };


    return table[n & 0xff] +
        table[(n >> 8) & 0xff] +
        table[(n >> 16) & 0xff] +
        table[(n >> 24) & 0xff];
}


int main()
{
    __int64 t;
    scanf("%I64d", &t);
    for (__int64 i = 1; i <= t; i++)
    {
        __int64 d;
        __int64 s1, s2;
        scanf("%I64d%I64d%I64d", &d, &s1, &s2);
        __int64 l;
        d++;
        while (1)
        {
            l = BitCount(d);
            if (BitCount(d) >= s1&&BitCount(d) <= s2)
            {
                printf("Case #%I64d: %I64d\n", i, d);
                break;
            }
            if (l < s1)
            {
                __int64 queshao = s1 - l;
                __int64 bit[35];
                __int64 pos = 0;
                while (d)
                {
                    bit[pos++] = d % 2;
                    d /= 2;
                }
                __int64 buwei = 0;
                for (__int64 pos1 = 0; pos1 < pos && buwei != queshao; pos1++)
                {
                    if (bit[pos1] == 0)
                    {
                        bit[pos1] = 1;
                        buwei += 1;
                    }
                }
                __int64 s = 0;
                for (__int64 j = 0, meiwei = 1; j < pos; j++, meiwei *= 2)
                    s += meiwei*bit[j];
                printf("Case #%I64d: %I64d\n", i, s);
                break;
            }
            else //l>s2
            {
                __int64 bit[35];
                __int64 pos = 0;
                int dt = d;
                while (dt)
                {
                    bit[pos] = dt % 2;
                    dt /= 2;
                    pos += 1;
                }
                for (__int64 pos1 = 0; pos1 < pos; pos1++)
                {
                    if (bit[pos1] == 1)
                    {
                        d += 1 << pos1;
                        break;
                    }
                }
                if (BitCount(d) >= s1&&BitCount(d) <= s2)
                {
                    printf("Case #%I64d: %I64d\n", i, d);
                    break;
                }
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值