题意:
t组样例,
每次给出一个n,
一开始你有一个细菌 mass=1,
细菌可以分裂,每个细菌可以分裂成两个,
比如 mass=1的细菌分成两个mass=0.5的细菌,
每晚所有的细菌都会质量+1;
你可以决定每天分裂几个。
要求是输出 总质量到达n至少要经过几天
标程:
#include <bits/stdc++.h>
using namespace std;
void solve(){
vector<int>inc;
int N;
cin>>N;
//construct sequence 1, 2, 4, ... while sum <= N
for (int i=1;i<=N;i*=2){
inc.push_back(i);
N-=i;
}
//if sum is not N, we insert and sort
if (N>0){
inc.push_back(N);
sort(inc.begin(),inc.end());
}
cout<<inc.size()-1<<endl;
for (int i=1;i<(int)inc.size();i++)
cout<<inc[i]-inc[i-1]<<' ';
cout<<endl;
}
int main(){
int t; cin>>t;
while (t--)
solve();
}
题解思路:
像上面这些先不去考虑。
试着考虑一下,
比如现在一共有c个细菌,如果全都不分裂,那么一天过去了,会增加c个。
如果全都分裂,那就会增加2c个。要是其中只有一个分裂,那就会增加c+1个,每次增加的个数与分裂之后一共有多少个细菌有关。
即 c <= 每次增加的个数 <= 2c;
为了最少的时间达到n,
所以每次增加的个数肯定要取最多的。
也就是按照每次乘以2;
for (int i=1;i<=N;i*=2){
inc.push_back(i);
N-=i;
}
这里如果n最后不为0的话,把剩下的n也放到数组里,
然后再排序,
if (N>0){
inc.push_back(N);
sort(inc.begin(),inc.end());
}
最后
cout<<inc.size()-1<<endl;
for (int i=1;i<(int)inc.size();i++)
cout<<inc[i]-inc[i-1]<<' ';
cout<<endl;
inc[i]-inc[i-1],这次增加的比上次增加的多了几个,就代表分裂了几个。