1. 程式人生 > >Codeforces Round #529 (Div. 3) C. Powers Of Two

Codeforces Round #529 (Div. 3) C. Powers Of Two

http://codeforces.com/contest/1095/problem/C

題意:給n找出k個2的冪,加起來正好等於n。例如 9,4:9 = 1 + 2 + 2 + 4

思路:首先任何數都能表示成2的次冪的和,其次很容易發現,n和k都是二的次冪的情況是最基礎的,因為可以分成k個n/k,而n/k一定是二的次冪。

所以,可以得出結論,只要n是2的次冪,且k<=n,一定有解。因為k一定能分成二的次冪的和。假如是 8,3就可以分成 4,1,、4,2這兩種基礎情況。

如果n不是2的次冪,那n也一定能分為,一個n以內最大的2的次冪加上另一個數,例如 36 = 32 + 4 、 63 = 32 + 31,由上可知,2的次冪是一定有解的,所以我們要給2的次冪儘量少分k,要給剩下的那個可能不是2的次冪的數多分k,好讓那個數能夠繼續分成2的次冪和其他數的和。例如,63 = 32 + 31。32是一定有解得,31還要分成16 15 所以,要給31多分k。

 1 #include <iostream>
 2 #include <vector>
 3 
 4 bool judge(int n){
 5     if((n > 0) && ((n & (n - 1)) == 0)) return 1;
 6     return 0;
 7 }
 8 int find_near_power(int n){
 9     long long m = 1;
10     int cnt = 0;
11     while(m <= n){
12         m = m * 2
; 13 cnt++; 14 } 15 return 1 << (cnt - 1); 16 } 17 void dfs(int n, int k, std::vector<int> &res, int &ok){ 18 if(n == 0 && k == 0) return; 19 else if((n > 0 && k <= 0) || (k <= 0 && n > 0)) { 20 ok = 0; 21 return
; 22 } 23 24 if(n%2 == 1){ 25 k = k - 1; 26 res.push_back(1); 27 dfs(n-1, k, res, ok); 28 } else { 29 //std::cout << "n " << n << std::endl; 30 if(judge(n)){ 31 if(judge(k)){ 32 for(int i = 0; i < k; ++i){ 33 res.push_back(n/k); 34 } 35 } else { 36 int tmp = find_near_power(k); 37 dfs(n/2, tmp, res, ok); 38 dfs(n/2, k-tmp, res, ok); 39 //std::cout << "tmp " << tmp << std::endl; 40 } 41 } else { 42 int tmp = find_near_power(n); 43 //std::cout << "tmp " << tmp << std::endl; 44 if(n-tmp < k){ 45 dfs(tmp, k+tmp-n, res, ok); 46 dfs(n-tmp, n-tmp, res, ok); 47 } else { 48 dfs(tmp, 1, res, ok); 49 dfs(n-tmp, k-1, res, ok); 50 } 51 52 } 53 } 54 } 55 int main() 56 { 57 int n, k; 58 while(std::cin >> n >> k){ 59 if(n < k){ 60 std::cout << "NO" << std::endl; 61 continue; 62 } 63 int ok = 1; 64 std::vector<int> res; 65 dfs(n,k,res,ok); 66 if(ok == 1){ 67 std::cout << "YES" << std::endl; 68 for(int i = 0; i < k; ++ i){ 69 if(i == 0) std::cout << res[i]; 70 else std::cout << " " << res[i]; 71 } 72 std::cout << std::endl; 73 } else { 74 std::cout << "NO" << std::endl; 75 } 76 } 77 }