cf 1095c

#include <cstdio>
#include<iostream>
using namespace std;
int a[1000005];
int k, n, cnt;
int main()
{
	cin >> n >> k;
	int t = 1;
	while (n)
	{
		if (n & 1)//看n有多少个1
		{
			a[cnt++] = t;
			/*cout << "a:" << a[cnt - 1]<<endl;*/
		}
		t <<= 1;//t乘以2
		n >>= 1;//n除以2
	}
	cnt--;
	/*cout << cnt << endl;*/
	int temp = 0;
	while ((cnt+1) < k)
	{
		while(a[temp]== 1)//判断是否是数字到了尽头
		{
			if (cnt == temp)//全部已经被除到了1但是还没有完成
			{
				cout << "NO";
				return 0;
			}
			temp++;
		}
		a[temp] >>= 1;//除以2
		a[++cnt] = a[temp];//外后加当前的数字除以2
	}
	if (cnt >= k)//cnt》=k时并没有入循环,k小了说明和不可能达到n
	{
		cout << "NO";
		return 0;
	}
	cout << "YES"<<endl;
	for (int i = 0; i < cnt+1; i++)//直接输出就好了
		cout << a[i]<<" ";
	return 0;

}
/*感觉自己对于位操作很不熟悉,对于二进制的东西也不熟悉,这道是div2难度的题我打了两个多小时
感觉可以针对的方向练习,每次比赛这种题都很不容易写出,主要是针对&|》》《《这几个操作符号和
二进制不太熟悉,继续加油*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值