zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    函数基础
    全局变量与类似配置文件的模块文件
    global语句(python学习手册422页)
    作用域实例
    变量名解析:LEGB原则
    作用域
    第三方库安装方法
    s[-1]和s[len(s)-1]
    查找特定后缀的文件
    logging日志管理-将日志写入文件
  • 原文地址:https://www.cnblogs.com/GeniusYang/p/10198475.html
Copyright © 2011-2022 走看看