题目链接:http://codeforces.com/contest/1095/problem/C
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
题意:n能否拆成k个2的整数次方相加,如果能输出YES以及一种拆法,否则输出NO
思路:先找出n的二进制里1的个数(设为ans),如果ans<k,将当前最高位1拆成两个次高位1,ans++,直到ans==k, 额……看代码吧
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int res[50];
int main() {
memset(res,0,sizeof(res));
int n,k;
scanf("%d%d",&n,&k);
if(k>n)
printf("NO\n");
else {
int ans=0,t=0;//ans是n的二进制里1的个数
int m=n;
while(m) {
if(m&1) {
ans++;
res[t]++;
}
m>>=1;
t++;
}
if(ans>k)
printf("NO\n");
else {
bool flag=false;
if(ans<k) {
for(int i=32; i>=0; i--) {
while(res[i]) { //将当前最高位1拆成两个次高位1
res[i]--;
res[i-1]+=2;
ans++; //1的个数++;
if(ans==k) {
flag=true;
break;
}
}
if(flag) break;
}
}
printf("YES\n");
int cnt=1;
for(int i=0; i<=32; i++) {
while(res[i]) {
printf("%d%c",(int)pow(2,i)," \n"[cnt==k]);
res[i]--;
cnt++;
}
}
}
}
return 0;
}