码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces C - Powers Of Two

时间:2018-12-28 15:20:50      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:初始   需要   mes   递归   vector   col   namespace   题意   一个   

题意:给出一个数字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;
}

 

CodeForces C - Powers Of Two

标签:初始   需要   mes   递归   vector   col   namespace   题意   一个   

原文地址:https://www.cnblogs.com/llzhh/p/10190520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!