1.题目描述:
The Next
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2024 Accepted Submission(s): 732
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.
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.
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
Recommend
2.题意概述:
T组测试数据。
L,S1,S2。
L的二进制中有x个1,x满足 S1<=x<=S2
求满足S1<=x<=S2的下一个数。
3.解题思路:
考虑通过比较当前的1的数目来进行最小的数的修正。
先将D加1,然后计算出D的1的数目tot,这时候比较tot和s1,s2的大小,这时候有两种情况:
1、sum<s1,这时我需要增加1的数目,因为要最小,所以我从右开始找到一个0(位置假设为i),将D加上2^i。
2、sum>s2,这时我需要减少1的数目,所以我从右开始找到一个1,将D加上2^i。
如此循环上述过程,直到符合sum符合s1,s2的条件。
上面操作的原因是:我加上2^i,就是将那一位由1变为0或者由0变为1,而我是从右边开始寻找的,可以保证每次所做的改变都是最小的。同时我的D是一直增加的,所以当条件满足时,就是那个最小的。
(好像这题还有个新姿势,就是lowbit,以后补上解法)
4.AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 40
using namespace std;
typedef long long ll;
char d[maxn];
ll T, D, cnt, s1, s2, kase = 0;
ll getbinary(ll x)
{
ll num = 0, t = 0;
while (x)
{
d[t++] = x % 2;
if (x & 1)
num++;
x /= 2;
}
return num;
}
int main()
{
scanf("%lld", &T);
while (T--)
{
memset(d, 0, sizeof(d));
scanf("%lld%lld%lld", &D, &s1, &s2);
ll y, sum, dis = 0, ans = 0, e = 1;
do
{
dis++;
y = D + dis;
sum = getbinary(y);
if (sum < s1)
{
ll add = s1 - sum;
cnt = 0;
while (add)
{
if (d[cnt] == 0)
{
d[cnt] = 1;
add--;
}
cnt++;
}
break;
}
} while (sum < s1 || sum > s2);
for (int i = 0; i < 40; i++)
{
if (d[i])
ans += e;
e *= 2;
}
printf("Case #%lld: ", ++kase);
printf("%lld\n", ans);
}
return 0;
}