Codeforces Round #529 -C- Powers Of Two(二進位制拆分)
A positive integer xx is called a power of two if it can be represented as x=2yx=2y, where yy is a non-negative integer. So, the powers of two are 1,2,4,8,16,…1,2,4,8,16,….
You are given two positive integers nn and kk. Your task is to represent nn as the sumof exactly kk powers of two.
Input
The only line of the input contains two integers nn and kk (1≤n≤1091≤n≤109, 1≤k≤2⋅1051≤k≤2⋅105).
Output
If it is impossible to represent nn as the sum of kk powers of two, print NO.
Otherwise, print YES, and then print kk positive integers b1,b2,…,bkb1,b2,…,bk such that each of bibi is a power of two, and ∑i=1kbi=n∑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的數量為最小需要的二進位制數,最多需要多少,是n個,因為都可以用1來表示,然後大一位的數代替即可,故可以表示的範圍為2進位制1的個數到n,這是可以表示出來的,可以從1進行累加到滿足,也可以從高位拆分,高位拆分在一般情況下可能更快
下面是程式碼:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
long long int a[505];
int m=0;
int tochange(int x) {
while(x) {
a[m++]=x%2;
x/=2;
}
}//轉成2進位制
int main() {
int n,k;
scanf("%d%d",&n,&k);
int ans=0;
tochange(n);
for(int t=m-1; t>=0; t--) {
if(a[t]==1) {
ans++;
}
}
if(k<ans||k>n) {
cout<<"NO"<<endl;
}//不滿足的情況
else {
cout<<"YES"<<endl;
if(ans==k) {//如果直接等於就不用拆分了
for(int t=0; t<m; t++) {
if(a[t]==1) {
long long int s1=pow(2,t);
printf("%lld ",s1);
}
}
} else {//從高位拆分,高位-1,低位+2,ans+1
int p=m-1;
while(ans!=k) {
while(a[p]>=1) {
a[p]--;
a[p-1]+=2;
ans++;
if(ans==k)
{
break;
}
}
p--;
}//輸出
for(int t=m-1; t>=0; t--) {
if(a[t]>=1) {
for(int j=0; j<a[t]; j++) {
long long int s2=pow(2,t);
printf("%lld ",s2);
}
}
}
}
}
return 0;
}