HDU 5491 The Next 貪心

The Next

Time Limit: 1 Sec  php

Memory Limit: 256 MBios

題目鏈接

http://acm.hdu.edu.cn/showproblem.php?pid=5491

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.c++

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.this

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.spa

Sample Input

3
11 2 4
22 3 3
15 2 5code

Sample Outputblog

Case #1: 12
Case #2: 25
Case #3: 17three

HINT

 

題意ip

給你一個D,保證D的二進制中1的數量在s1和s2之間ci

而後讓你求一個最小的數,使得這個數的二進制數量大於等於s1,小於等於s2,且大於 d

題解:

首先,這道題會爆int

咱們首先想想,只要d左移動一位,那麼這個數必定是符合的,因此就只用在d*2到d+1裏面去找就行了

我瞎想了幾個貪心策略,而後取的最優解……

1.看這個數+1合不合法

2.這個數找到最右邊的0,把這個0變成1以後,把這個1右邊的1都儘可能變成0

代碼:

//qscqesze
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 300006
#define mod 1000000007
#define eps 1e-9
#define e exp(1.0)
#define PI acos(-1)
const double EP  = 1E-10 ;
int Num;
//const int inf=0x7fffffff;
const ll inf=999999999;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//*************************************************************************************

int get(ll x)
{
    int c =0 ; // 計數器
    while (x >0)
    {
        if((x &1) ==1) // 當前位是1
            c++; ; // 計數器加1
        x >>=1 ; // 移位
    }
    return c ;
}
ll change(ll x,int num)
{
    for(int i=0;i<132;i++)
    {
        if((x&(1LL<<i))==0)
        {
            x|=(1LL<<i);
            num--;
        }
        if(num==0)
            break;
    }
    return x;
}

ll change2(ll x,int K,int s1,ll P)
{
    int l =0;

    for(int i=0;i<132;i++)
    {
        if((x&(1LL<<i))==0)
        {
            x|=(1LL<<i);
            l = i;
            break;
        }
    }

    int num = K+1;
    for(int i = l-1;i>=0;i--)
    {
        x-=(1LL<<i);
        num--;
        if(num==s1)
            break;
    }
    if(x>P*2)return P;
    return x;
}

int main()
{
    int t;scanf("%d",&t);
    for(int cas = 1;cas <= t;cas ++)
    {
        ll a=read(),s1=read(),s2=read();
        ll ans = a+1;
        printf("Case #%d: ",cas);
        int len = get(ans);
        if(len<=s2&&len>=s1)
        {
            printf("%I64d\n",ans);
            continue;
        }
        if(len<s1)
        {
            printf("%I64d\n",change(ans,s1-len));
            continue;
        }
        if(len>s2)
        {
            while(len>s2)
            {
                ans = change2(ans,len,s1,a);
                len = get(ans);
            }
            printf("%I64d\n",ans);
        }
    }
}
相關文章
相關標籤/搜索