HDU 5491.The Next【2015 ACM/ICPC Asia Regional Hefei Online】【方法】【9月30】

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  S1LS2 .
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 ( T300000 ).
Each test case consists of three integers  D S1 , and  S2 , as described above. It is guaranteed that  0D<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;
}



你可能感兴趣的:(C++,ACM,HDU)