E - Envious Exponents——二进制

发布时间:2024年01月18日

爱丽丝和鲍勃有一个整数 N.爱丽丝和鲍勃对他们的整数不满意。昨天晚上,他们去参加一个鸡尾酒会,发现另一对夫妇的整数完全相同!正因为如此,他们得到了一个新的整数。
Bob想给另一对夫妇留下深刻印象,因此他认为他们的新整数应该严格大于 N。
爱丽丝自己其实也喜欢一些特定的整数 k.因此,Alice认为,无论他们选择哪个整数,都应该可以将其写成 k 个 2 的不同幂。
鲍勃也是个吝啬鬼,所以他想尽量少花钱。由于整数的代价与其大小成正比,他希望得到一个尽可能小的整数。

题意:
给出 N,K,求 M ; M 为大于 N 的可以写成 k 个 2 的几次幂的最小值。

输入
包含两个整数的单行 N 和 k、 其中 1 ≤ N ≤ 1e18和 1 ≤ k ≤ 60。

输出
输出 ?M, M是大于 N 的最小整数,可以写成 k 个 2 的不同幂之和。

Input1
1 2
Output1
3

Input2
12 2
Output2
17

Input3
1 5
Output3
31

Input4
182 3
Output4
193
?

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef pair<int,int> PII;
const double PI=acos(-1.0);
const int N=2e6+10;
int b[63];
void find()
{
    b[0]=1;
    for (int i=1;i<61;i++) b[i]=b[i-1]*2;
}
int n,k;
bool vis[N];
void solve()
{
    find();
    cin>>n>>k;
    int num=0,cnt=0;
    int m=n;
    while (n)
    {
        if (n%2) 
        {
            vis[cnt]=1;
            num++;
        }
        n /=2;
        cnt++;
    }
    int ans=0;
    if (k>num)                          //当 k>num 时,个数不足,从低位开始补1就行
    {
        ans=m;
        k -=num;
        for (int i=0;i<61;i++)
        {
            if (!vis[i])
            {
                ans +=b[i];
                k--;
            }
            if (k<=0) break;
        }
        cout<<ans;
        return ;
    }
    if (k<num)                          //当 k<num 时,从低位开始将1替换成0,让num减小,直到num==k
    {
        for (int i=0;i<61;i++)
        {
            if (vis[i]==1)
            {
                vis[i]=0;
                num--;
                if (k==num) break;
            }
        }
    }
    int j=0;                            //此时 k==num,从低位找,找到第一个1;
    int l=0;                            //之后继续找,找到第一个0;
    while (vis[j]==0&&j<61) j++;        //将0之前的1都清空,将这个0变成1,再从低位开始补满k个1
    while (vis[j]==1&&j<61) 
    {
        j++;
        l++;
    }
    vis[j]=1;
    l--;
    for (int i=0;i<j;i++) vis[i]=0;
    for (int i=0;i<61;i++)
    {
        if (vis[i]) ans +=b[i];
        else if (!vis[i]&&l>0)
        {
            ans +=b[i];
            l--;
        }
    }
    cout<<ans;
}
signed main()
{
    ios;
    int T=1;
    //cin>>T;
    while (T--) solve();
    return 0;
}

文章来源:https://blog.csdn.net/m0_74403543/article/details/135683673
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。