• Codeforces 916B


    思路:

    先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成。

    通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下一位那么就全部转换过去,如果不能就一个也不要转换,不然会导致字典序损失。

    然后从最小的位开始转换,每次取出最小的位一个数,转换成下一位的两个,直到不能转换为止,这样就能保证字典序最大了,这个用优先队列维护下,可以直接求出来,直接for就可以了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    int a[200]={0};
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        ll n;
        ll k;
        cin>>n>>k;
        for(int i=0;i<=62;i++){
            if(n&(1ll<<i))a[i+100]=1;
        }
        int cnt=0;
        for(int i=0;i<=62;i++){
            if(a[i+100])cnt++;
        }
    
        if(cnt>k){
            cout<<"No"<<endl;
            return 0;
        }
        else if(cnt==k){
            cout<<"Yes"<<endl;
            for(int i=62;i>=0;i--)if(a[i+100])cout<<i<<' ';
            cout<<endl;
            return 0;
        }
        else{
                ll t=k-cnt;
                while(true)
                {
                    bool f=true;
                    for(int i=62;i>=-100;i--){
                        if(a[i+100]){
                            if(t>=a[i+100]){
                                t-=a[i+100];
                                a[i+99]+=a[i+100]*2;
                                a[i+100]=0;
                                f=false;
                            }
                            break;
                        }
                    }
                    if(f||t==0)break;
                }
            priority_queue<ll,vector<ll>,greater<ll> >q;
            for(int i=62;i>=-100;i--){
                if(a[i+100]){
                    for(int j=0;j<a[i+100];j++)q.push((ll)i);
                }
            }
            while(t){
                if(q.empty())break;
                ll now=q.top();
                q.pop();
                t--;
                q.push(now-1);
                q.push(now-1);
            }
            cout<<"Yes"<<endl;
            vector<ll>vc;
            while(!q.empty()){
                vc.pb(q.top());
                q.pop();
            }
            for(int i=vc.size()-1;i>=0;i--)cout<<vc[i]<<' ';
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Using sudo inside a docker container
    python enumerate用法总结
    如何保存Keras模型
    python pickle模块
    如何选择开源项目的license
    github在线创建文件夹
    关于python3.4版本中的zip函数
    使用sqoop 在关系型数据库和Hadoop之间实现数据的抽取
    HBase Shell 常见操作
    Java API 实现HBase的数据添加与过滤查询
  • 原文地址:https://www.cnblogs.com/widsom/p/8320588.html
Copyright © 2020-2023  润新知