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;
}
原文地址:https://www.cnblogs.com/wkfvawl/p/10505837.html