https://codeforces.com/contest/1348/problem/D
题意:
初始有一个细菌,重量为1。每个细菌白天可以分裂成两个,重量均为原来的一半。每个夜晚,每个细菌会增加1重量
现在你可以决定每个白天有几个细菌分裂,问至少经过几晚细菌的总重量恰为n。输出每天有几个细菌分裂
思路:
分裂不会增加总重量,故只用考虑夜晚增加的重量
贪心。假设前 d 天每个细菌都分裂,那么第 d 夜后总重量为 \(1(初始重量)+2^2+2^2+\cdots 2^d = 2^{d+1}-1\)
还需要 \(k=n-(2^{d+1}-1)\) 。注意到每晚增加的重量不小于前一晚增加的重量,所以 k 不能在最后一晚,而应插入到中间的一个位置使数组递增。实测用 sort 排序跟手动插入速度一样
#include <bits/stdc++.h>
using namespace std;
int a[35];
signed main()
{
int T; scanf("%d", &T); while(T--)
{
int n, d; scanf("%d", &n);
for(d = 0; (1<<d)-1 < n; d++) a[d] = 1<<d;
a[d-1] = n+1-a[d-1];
sort(a, a+d);
printf("%d\n", d - 1);
for(int i = 1; i < d; i++)
printf("%d ", a[i]-a[i-1]);
puts("");
}
return 0;
}