CodeForces - 1095C 位运算的处理 存幂次 标记数目 有点陌生

14 篇文章 1 订阅
8 篇文章 0 订阅

题目

在这里插入图片描述

题解思路

将数字转换成二进制处理,也叫位运算。
从最高位开始往下压缩,每次压缩都能提供1的贡献,因为本来是一个数,现在变成两个数,这样下一位的标记数需要加2,当压缩到1时还是弄不出这个K值就不能表示。
此外最小的K值就是用数表示二进制中的所有1的个数,最大就是数本身(全转化为1)。 (可以进行提前特判)

AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;

const  int  INF =  0x3f3f3f3f;

long long a[100];
long long vis[100];
int main ()
{
    ios::sync_with_stdio(false);
    vector <long long > ans ;
    long long  n,k;
    cin>>n>>k;
    long long  mi = 0 ;
    a[0] = 1;
    for (int i = 1 ; i < 31 ; i++ )
        a[i] = a[i-1]*2;
    for (int i = 31 ; i >= 0 ; i-- )
    {
        int t = n >> i & 1 ;
        if ( t == 1 )
        {
            vis[i] = 1;
            mi += 1 ;
        }
    }
    if ( mi <= k && k <= n )
    {
        long long  p1 = k - mi ;
        long long p2 ;
        for (int i = 31 ; i > 0 ; i-- )
        {
            if (vis[i] > 0 )
            {
                p2 = i;
                break;
            }
        }
        while(p1!=0 && p2 > 0 )
        {
            vis[p2]--;
            vis[p2-1]+=2;
            if ( vis[p2] == 0 )
            {
                p2--;
            }
            p1--;
        }
        if ( p1 == 0 )
        {
            cout<<"YES\n";

            for (int i = 0 ; i <= 31 ; i++ )
            {
                for (int k = vis[i] ; k>= 1 ; k-- )
                {
                    cout<<a[i]<<" ";
                }
        }
        }else
            cout<<"NO\n";
    }
    else
        cout<<"NO\n";
    return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值