标签:初始 需要 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; }
标签:初始 需要 mes 递归 vector col namespace 题意 一个
原文地址:https://www.cnblogs.com/llzhh/p/10190520.html