寒假集训第二次测试(E - Envious Exponents )

/problems/enviousexponents/file/statement/en/img-0001.jpg

Alice and Bob have an integer NN. Alice and Bob are not happy with their integer. Last night they went to a cocktail party and found that another couple had the exact same integer! Because of that they are getting a new integer.

Bob wants to impress the other couple and therefore he thinks their new integer should be strictly larger than NN.

Alice herself is actually fond of some specific integer kk. Therefore, Alice thinks that whatever integer they pick, it should be possible to write it as a sum of kk distinct powers of 22.

Bob is also a cheapskate, therefore he wants to spend as little money as possible. Since the cost of an integer is proportional to its size, he wants to get an integer that is as small as possible.

Input

  • A single line containing two integers NN and kk, with 1≤N≤10181≤N≤1018 and 1≤k≤601≤k≤60.

Output

Output MM, the smallest integer larger than NN that can be written as the sum of exactly kk distinct powers of 22.

Sample Input 1 Sample Output 1
1 2
3
Sample Input 2 Sample Output 2
12 2
17
Sample Input 3 Sample Output 3
1 5
31
Sample Input 4 Sample Output 4
182 3
193

题意:

给你一个1e18的数n,给你一个k值,让你求出有k个2的不同次幂之和大于这个n,并让你求出ans的最小值;

思路:将n转化成2进制,因为n的二进制中出现多少1,就代表n由多少个不同2的不同次幂之和;所以需要比较这个数与k的关系;如果cnt>k的话转化成cnt==k进行操作,找到从低位到高位第一个前置0将这个0转化成1,再将后面的0都变成1;当cnt<k;就单纯的将后面的0都转换成1,要是不够的话往高位上加。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn =1e5+10;
ll n;
ll k;
ll get(int x,int y)
{
    ll ans=1;
    ll res=x;
    while(y)
    {
        if(y&1)
        {
            ans*=res;
        }
        res*=res;
        y/=2;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    ll a[maxn];
    memset(a,0,sizeof(a));
    int tot=0;
    while(n)
    {
        a[tot++]=n%2;
        n/=2;
    }
    int cnt=0;
    for(int i=0;i<tot;i++)
    {
        if(a[i]==1)
        {
            cnt++;
        }
    }
    if(cnt>k)
    {
        for(int i=0;i<tot;i++)
        {
            if(a[i])
            {
                a[i]=0;
                cnt--;
            }
            if(cnt==k)
                break;
        }
    }
    if(cnt==k)
    {
        int i=0;
        int flag=0;
        int flag1=0;
        int x;
        while(i<tot)
        {
            if(a[i]==1)
            {
                flag=1;
            }
            if(!a[i]&&flag)
            {
                x=i;
                flag1=1;
                break;
            }
            i++;
        }
        if(!flag1)
        {
            for(int i=0;i<tot;i++)
                a[i]=0;
            a[tot++]=1;
            for(int i=0;i<k-1;i++)
            {
                a[i]=1;
            }
        }
        else
        {
            a[x]=1;
            a[x-1]=0;
            int z=0;
            for(int i=0;i<x;i++)
            {
                if(a[i])
                {
                    a[i]=0;
                    z++;
                }
            }
            for(int i=0;i<z;i++)
            {
                a[i]=1;
            }
        }
        ll ans=0;
        for(int i=0;i<tot;i++)
        {
            if(a[i])
            {
                ans+=get(2,i);
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    else
    {
        int w=k-cnt;
        for(int i=0;i<tot;i++)
        {
            if(!a[i])
            {
                a[i]=1;
                w--;
            }
            if(w==0) break;
        }
        if(w)
        {
           ll ans=0;
           for(int i=0;i<k;i++)
           {
              ans+=get(2,i);
           }
           cout<<ans<<endl;
           return 0;
        }
        ll ans=0;
        for(int i=0;i<tot;i++)
        {
            if(a[i])
            {
                ans+=get(2,i);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
发布了12 篇原创文章 · 获赞 0 · 访问量 345

猜你喜欢

转载自blog.csdn.net/Ramzes_666_fan/article/details/103958778