HDU 5491 The Next(技巧性模拟)

来源:互联网 发布:centos忘记密码 编辑:程序博客网 时间:2024/05/14 22:16

Let LL denote the number of 1s in integer DD’s binary representation. Given two integers S1S1 and S2S2, we call DD a WYH number if S1LS2S1≤L≤S2
With a given DD, we would like to find the next WYH number YY, which is JUST larger than DD. In other words, YY is the smallest WYH number among the numbers larger than DD. Please write a program to solve this problem. 
Input
The first line of input contains a number TT indicating the number of test cases (T300000T≤300000). 
Each test case consists of three integers DDS1S1, and S2S2, as described above. It is guaranteed that 0D<2310≤D<231 and DD is a WYH number. 
Output
For each test case, output a single line consisting of “Case #X: Y”. XX is the test case number starting from 1. YY is the next WYH number.
Sample Input
311 2 422 3 315 2 5
Sample Output
Case #1: 12Case #2: 25Case #3: 17

题解:

题意:

给你一个数x,和两个数字s1,s2,让你找出大于x的满足二进制中1的个数在s1和s2之间的数的最小值

思路:

转化成二进制以后,从右往左扫,如果1的个数小于了s1,将扫到的0变成1,如果个数大于s2,将扫到的1进位,循环到符合条件为止

代码:

#include<iostream>#include<cstring>#include<stdio.h>#include<math.h>#include<string>#include<stdio.h>#include<queue>#include<stack>#include<map>#include<vector>#include<deque>#include<algorithm>#define ll long longusing namespace std;ll a[40];int cmp(ll x,ll y){    return x>y;}int main(){    int test,i,j,n,m,q,s1,s2,len,num,tag;    ll d,s,x,t;    scanf("%d",&test);    for(q=1;q<=test;q++)    {        scanf("%lld%d%d",&x,&s1,&s2);        memset(a,0,sizeof(a));        len=0;        num=0;        x++;        t=x;        while(x>0)        {            a[len]=x%2;            x/=2;            len++;            if(a[len-1]==1)                num++;        }        s=0,d=1;        while(num<s1||num>s2)        {            while(num<s1)            {                tag=0;                for(i=0;i<len;i++)                {                    if(a[i]==0)                    {                        tag=1;                        a[i]=1;                        num++;                        if(num>=s1)                            break;                    }                }                if(!tag)                {                    a[len]=1;                    num++;                    len++;                }            }            while(num>s2)            {                for(i=0;i<len;i++)                {                    if(a[i])                    {                        a[i]=0;                        num--;                        j=i+1;                        if(j==len)                        {                            a[j]=1;                            len++;                            num++;                            break;                        }                        while(j<len&&a[j])                        {                            a[j]=0;                            num--;                            j++;                        }                        if(j==len)                        {                            a[j]=1;                            num++;                            len++;                            break;                        }                        else                        {                            a[j]=1;                            num++;                        }                        if(num<=s2)                            break;                    }                }            }        }        for(i=0;i<len;i++)        {            s=s+d*a[i];            d*=2;        }        printf("Case #%d: %lld\n",q,s);    }    return 0;}



原创粉丝点击