zoukankan      html  css  js  c++  java
  • CF 1095C Powers Of Two(二进制拆分)

    A positive integer xx is called a power of two if it can be represented as x=2y, where y is a non-negative integer. So, the powers of two are 1,2,4,8,16,…

    You are given two positive integers nn and k. Your task is to represent nn as the sumof exactly k powers of two.

    Input

    The only line of the input contains two integers nn and k (1≤n≤109, 1≤k≤2⋅105).

    Output

    If it is impossible to represent nn as the sum of k powers of two, print NO.

    Otherwise, print YES, and then print kk positive integers b1,b2,…,bk such that each of bibi is a power of two, and ∑i=1kbi=n. If there are multiple answers, you may print any of them.

    Examples

    Input

    9 4

    Output

    YES
    1 2 2 4

    Input

    8 1

    Output

    YES
    8

    Input

    5 1

    Output

    NO

    Input

    3 7

    Output

    NO
    题目意思:给定一个数,让你用1,2,4,8等2的倍数表示出来,并且要用指定的k个数,输出一种即可。

    解题思路:我们知道任意一个数都可以通过2的倍数组成,这其中的原因可以通过十进制转换二进制来说明。

    如果该数的二进制对应数中1的个数大于k,那么很显然不会有k个2的倍数组成该数;如果恰好相等,那么只需要将二进制各个位上的1转换为对应的十进制即可;如果该数的二进制对应数中1的个数小于k,那么就需要拆分二进制了,这里我从高位来开始拆分,每当高位-1时,对应的下一位将会+2,这里存放二进制的数组里将不再仅仅存放0和1了,这时候存放的是对应二进制位数的个数了,只要拆分到恰够k个即可。同时要注意pow函数的使用,这个函数返回值是double类型的,注意转换。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int main()
    {
        int n,k,counts,i,j,x,y,a,ans;
        int b[110];
        scanf("%d%d",&n,&k);
        counts=0;
        x=0;
        a=n;
        while(a)
        {
            if(a%2)
            {
                counts++;
            }
            b[x]=a%2;
            x++;
            a/=2;
        }
        //printf("%d
    ",counts);
        //printf("%d
    ",x);
        if(k<counts||k>n)///不满足条件的情况
        {
            printf("NO
    ");
        }
        else
        {
            printf("YES
    ");
            if(counts==k)///直接按照进制,不需要拆分
            {
                for(i=0; i<x; i++)
                {
                    if(b[i])
                    {
                        ans=int(pow(2,i));
                        printf("%d ",ans);
                    }
                }
            }
            else///即k>counts,从高位开始拆分,高位-1,相当于低位+2,counts+1
            {
                y=x-1;///最高位
                while(counts!=k)///终止条件
                {
                    while(b[y]>=1)
                    {
                        b[y]--;
                        b[y-1]+=2;
                        counts++;
                        if(counts==k)
                        {
                            break;
                        }
                    }
                    y--;
                }
                for(i=x-1; i>=0; i--)///输出
                {
                    if(b[i]>=1)///注意这里b[i]上的值代表的是该位上对应2^i的个数
                    {
                        for(j=0; j<b[i]; j++)
                        {
                            ans=int(pow(2,i));
                            printf("%d ",ans);
                        }
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Drupal 7 中文安装教程
    苹果之硬盘启动安装
    STP详解
    RedHat Install
    Linux密码更改
    win8.1开启虚拟wifi
    跳过安装密钥安装系统
    虚拟机中Linux安装Tools
    桌面虚拟化之XenDesktop7
    桌面虚拟化之部署DDC-5.6
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/10505837.html
Copyright © 2011-2022 走看看