寒假训练赛Ⅰ I题

I. Powers Of Two

题目链接
题目大意:给出一个n和k,计算出n由k个2^p(p∈Z+)相加而成,求这k个数的组合。
思路:先算出n的二进制形式,然后计算二进制上有几个1,记为p,并将每个是1的位置对应十进制的数由大到小存入队列中,p是组合成n的最小个数以及队列的size,如果n<k或者k<p,就不存在这种组合,否则就存在。如果存在,意味着p<=k,就需要将队列中的数一一取出除以二,然后再放入队列,此时p++,注意如果取出的是1,就不用除,直接重新放入队列即可,这样子反复操作直到p=k,然后一一pop出队列打印即可。
代码

#include <cstdio>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;
int d[10005],a[10005];
int change(int n){
	int p=0;
	while(n){//十进制转化二进制。
		d[p++]=n%2; 
		n/=2; 
	}
	int pp=0;
	for(int i=0;i<p;i++){
		if(d[i]){
			a[pp++]=pow(2,i);//将二进制每一位转化成十进制数。
		}
	}
	return pp;//pp就是n拆出来的最少个数
}
int main(){
	queue<int>que;
	int n,k;
	scanf("%d%d",&n,&k);
	int p=change(n);
	if(n<k) puts("NO");
	else if(k<p) puts("NO");
	else{
		for(int i=p-1;i>=0;i--){
			que.push(a[i]);
		}
		while(que.size()!=k){
			int m=que.front();
			if(m>1){
				que.pop(); 
				m/=2;
				que.push(m);
				que.push(m);
			}
			else{
				que.pop();
				que.push(1);//是1的话,就弹出再放入,让它到队列最下面。
			}
		}
		puts("YES");
		while(!que.empty()){
			int res=que.front();
			que.pop();
			printf("%d ",res);//一个一个pop出来输出
		}
	}
	return 0;
} 
发布了32 篇原创文章 · 获赞 0 · 访问量 630

猜你喜欢

转载自blog.csdn.net/weixin_45794203/article/details/104027246
今日推荐