zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    书摘--可能与不可能的边界
    电影-茶室
    使用unittest,if __name__ == '__main__':里代码不执行的解决办法
    Pycharm中配置鼠标悬停快速提示方法参数
    Python 解决pip使用超时的问题
    Linux性能监控命令——sar详解
    Linux系统管理
    Linux top命令的用法详细详解
    CentOs7排查CPU高占用
    centos 7 查看磁盘io ,找出占用io读写很高的进程
  • 原文地址:https://www.cnblogs.com/widsom/p/8320588.html
Copyright © 2011-2022 走看看