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;
}