HDU 5491 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.


 


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 

這道題在比賽的時候我就是用的這個方法,可是一直超時。後來從新寫了一遍,用了G++過了。this

思路:spa

從小到大找一定超,我看限制條件一的個數是0~32差很少,這麼個循環是不會超時的。我就從i->s1~s2循環,裏面找一的個數爲i的。code

這裏由於要i個1,而後又要比L大那麼把第i個1前移一位。blog

下面這裏分兩個狀況:three

以須要3個1爲例ip

①11011->11100input

②10111->11001若是進位了,就在末尾補1.it

還有一種狀況就是找不到第i個1:就從後往前變0爲1,直到知足i個1.io

而後去每種1個數的最小值。class

證實正確性:

試想要i個1那麼不夠的話還要比他大是否是日後補就行,由於1放在越後面越小。

要是夠,由於要比他大,這裏可知1的個數比須要的多。咱們就要刪掉1,那麼刪哪些呢?到第i個1爲止,你後面在怎麼變①後面1變少,數值變小,不行②1變多,咱們如今要刪掉1,不行;

因此後面的都不行,那麼第i個1要進位了。而後進位完,1不夠了,最小就往最後面補。

#include<stdio.h>
int main()
{
    int T,s1,s2;
    __int64 L,p;
    int cas=0;

    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%d%d",&L,&s1,&s2);
         p=(__int64)1<<40;
        
        if(L==0&&s1==0&&s2==0){
            printf("Case #%d: 0\n",++cas);
        continue;
        }
        int flag=0;
        __int64 t;
        for(int i=s1;i<=s2;i++)
        {
            int s=0,f=0;
            t=(__int64)0;
            for(int j=32;j>=0;j--)
            {
                if(L&((__int64)1<<j))s++;
                if(s==i)
                {
                    int z,k;
                    for(k=j;k<=32;k++)
                    {if(L&((__int64)1<<k));
                    else {
                        t|=(__int64)1<<k;
                    break;
                    }
                    }
                    
                    z=1;
                     for(int kk=k+1;kk<=32;kk++)
                     {
                         if(L&((__int64)1<<kk))t|=(__int64)1<<kk,z++;
                     }
                     z=i-z;
                     for(k=0;k<=32&&z>0;k++)t|=(__int64)1<<k,z--;
                     p=p>t?t:p; 
                
                f=1;
                break;
                }     
            }
            if(!f)
            {
                s=i-s;
                t=L;
                for(int k=0;k<=32&&s>0;k++){
                if(L&((__int64)1<<k));
                else t|=(__int64)1<<k,s--;
                }
                p=p>t?t:p; 
                
            }
            
        }
        printf("Case #%d: %I64d\n",++cas,p);
    }
} 
相關文章
相關標籤/搜索