The Next
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
这个题直接爆搜找是会超时的。方法:找到二进制1的个数比s1小的数,然后最小位往前是0的变1,直到1的个数等于s1。代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int T,kase=1;
scanf("%d",&T);
while(T--){
long long D,s1,s2,cnt;
scanf("%lld%lld%lld",&D,&s1,&s2);
for(long long i=D+1;;i++){
long long n=i,f[100]={0},t=0;
cnt=0;
while(n){
f[t++]=n%2;
n/=2;
if(f[t-1]==1) cnt++;
}
if(cnt>=s1&&cnt<=s2){//符合题意
printf("Case #%d: %lld\n",kase++,i);
break;
}
else if(cnt<s1){//可以变
t=0;
while(cnt<s1){
if(f[t]==0){
cnt++;
f[t]=1;
}
t++;
}
long long sum=0,x=1;
for(int j=0;j<100;j++){
sum+=(f[j]*x);
x*=2;
}
printf("Case #%d: %lld\n",kase++,sum);
break;
}
}
}
return 0;
}
然后是爆搜程序,可以拿去对拍:#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
int T,kase=1;
scanf("%d",&T);
while(T--){
int D,s1,s2;
scanf("%d%d%d",&D,&s1,&s2);
for(int i=D+1;;i++){
int n=i,cnt=0;
while(n){
if(n%2==1) cnt++;
n/=2;
}
if(cnt>=s1&&cnt<=s2){
printf("Case #%d: %d\n",kase++,i);
break;
}
}
}
return 0;
}