C. Powers Of Two 二進位制
阿新 • • 發佈:2019-01-01
題目連結:http://codeforces.com/contest/1095/problem/C
題目大意:給你兩個整數n和k,要求把n拆成k個2的冪的和。1 2 4 8 16…。如果無法做到就輸出NO,能夠做到就輸出YES,並且輸出k個2的冪加數。
思路:開始沒有往二進位制的方向想。只判斷出是能不能滿足條件。方案不知道怎麼構造。
後來用了二進位制。那麼n的二進位制有多少個1.這就是k的最小值。因為可以把高位的1拆成兩個低進位制的1。所以把所有高位的1的全部拆成最低位的1。就是k的最大取值。也就是n個2^0。
思考:因為後面的迴圈結束時沒有判斷所有的低位的和是否<k。所以第二天WA 29。-59。慘痛的教訓。。。
#include<bits/stdc++.h> using namespace std; #define LL long long const int mod=1000000007; char a[35]; int b[35]; int main() { int n, k, s=0; scanf("%d%d",&n,&k); if(k>n) { printf("NO\n"); return 0; } for(int i=0;i<32;i++) { a[i]=((n>>i)&1)+'0'; } for(int i=32;i>=0;i--) { if(a[i-1]=='1') { n=i-1; for(int j=i-1;j>=0;j--) { b[j]=a[j]-'0'; s+=b[j]; } break; } } if(k<s) { printf("NO\n"); return 0; } else { for(int i=n;i>=0;i--) { if(k>=s+b[i]&&i>0) { b[i-1]+=b[i]*2; s+=b[i]; b[i]=0; } else if(k<s+b[i]) { int m=k-s; b[i-1]+=2*m; b[i]-=m; break; } else { printf("NO\n"); return 0; } } printf("YES\n"); for(int i=0;i<=n;i++) { while(b[i]--) { printf("%d ",(int)pow(2, i)); } } } return 0;