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
不想写,找了个别人的.
思路:
考虑通过比较当前的1的数目来进行最小的数的修正。
先将D加1,然后计算出D的1的数目tot,这时候比较tot和s1,s2的大小,这时候有两种情况:
1、tot<s1,这时我需要增加1的数目,因为要最小,所以我从右开始找到一个0(位置假设为i),将D加上2^i。
2、tot>s2,这时我需要减少1的数目,所以我从右开始找到一个1,将D加上2^i。
如此循环上述过程,直到符合tot符合s1,s2的条件。
上面操作的原因是:我加上2^i,就是将那一位由1变为0或者由0变为1,而我是从右边开始寻找的,可以保证每次所做的改变都是最小的。同时我的D是一直增加的,所以当条件满足时,就是那个最小的。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 #include <stack> 15 using namespace std; 16 int dirx[]={0,0,-1,1}; 17 int diry[]={-1,1,0,0}; 18 #define PI acos(-1.0) 19 #define max(a,b) (a) > (b) ? (a) : (b) 20 #define min(a,b) (a) < (b) ? (a) : (b) 21 #define ll long long 22 #define eps 1e-10 23 #define MOD 1000000007 24 #define N 100 25 #define inf 1e12 26 ll d,s1,s2; 27 ll num[N]; 28 ll k; 29 ll count_(ll dd){ 30 memset(num,0,sizeof(num)); 31 ll cnt=0; 32 k=0; 33 while(dd){ 34 if(dd&1) cnt++; 35 num[k++]=(dd&1); 36 dd>>=1; 37 } 38 num[k++]=0; 39 40 return cnt; 41 } 42 int main() 43 { 44 ll ac=0; 45 ll t; 46 scanf("%I64d",&t); 47 while(t--){ 48 scanf("%I64d%I64d%I64d",&d,&s1,&s2); 49 50 ll dd=d+1; 51 52 while(1){ 53 ll tmp=count_(dd); 54 55 if(tmp<s1){ 56 for(ll i=0;i<k;i++){ 57 if(num[i]==0){ 58 dd+=(1<<i); 59 break; 60 } 61 } 62 }else if(tmp>s2){ 63 for(ll i=0;i<k;i++){ 64 if(num[i]==1){ 65 dd+=(1<<i); 66 break; 67 } 68 } 69 }else{ 70 break; 71 } 72 } 73 printf("Case #%I64d: ",++ac); 74 printf("%I64d ",dd); 75 76 } 77 return 0; 78 }