CodeForces C - Powers Of Two

题意:给出一个数字n和k,使得k个数字加起来的和等于n。k个数字必须是2的幂次,比如1,2,4,8.

解法:首先排除k大于n的情况,这样即使全选1也不能满足。

  比赛时候想得做法是,先把2的幂次打表,然后尽量塞最大的进去。

  1.如果塞着塞着n等于0,必定有解。

    1.k不等于0,那只需要把大于1的数字拆出来,自己除以2,并且放另一半在数组后面。如4 2,塞进去4,变成0 1,这时候只需要拆4为2 + 2即可。

    2.k恰好也等于0,那直接返回,有解。如4 1,塞进去4。

  2.如果k等于0但是n不等于0,那无解。如5 1。

虽然ac了,但是这种方法并不好写,也不简便。后来学习别人的代码,发现只要改变一些思路就可以写的很简单。

更好的解法:先特判k大于n的情况

      然后开一个大小为k的数组ans,初始化为1.并且将n减去k。这时候只需要k个数字不断往上翻倍即可。

      遍历数组ans,遍历每个元素。for(i,0:k)while(只要当前第i个元素ans[i]小于n,则使得n减去ans[i],然后当前元素a*=2)

      如果最后n还是不为0,那么就输出no,否则把数组ans输出即可。

我就不把我当时写的可长的递归贴出来了,只贴这种很好写的。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, k;

int main() {
    cin >> n >> k;
    if(n < k) {
        cout << "NO" << endl;
        return 0;
    }
    vector<int> vec(k, 1);
    n -= k;
    for(int i = 0; i < k; ++i) {
        while(vec[i] <= n) {
            n -= vec[i];
            vec[i] *= 2;
        }
    }
    if(n) {
        cout << "NO" << endl;
    } else {
        cout << "YES" << endl;
        for(int i =  0; i < k; ++i) {
            cout << vec[i] << (i == k - 1 ? '\n' : ' ');
        }
    }
    return 0;
}

 

posted @ 2018-12-28 14:47  llzhh  阅读(157)  评论(0编辑  收藏  举报