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 }

 

posted @ 2018-12-30 00:18  GeniusYang  阅读(168)  评论(0编辑  收藏  举报