CF1348 D. Phoenix and Science

9 篇文章 0 订阅
6 篇文章 0 订阅

CF1348 D. Phoenix and Science

Question

一开始有1个细菌,他的权值为1。白天的时候1个细菌可以分裂成2个,也可以不分裂,晚上的时候1个细菌会增加权值1,求最少要多少天能够到达所有权值的和恰好为n,并且给出对应n天每天有几个细菌要分裂。

Solution

设需要 T T T天。
最快的增加方法为每次所有细菌分裂为 2 2 2个,晚上加上分裂后细菌的数量,那么 T = l o g 2 ( n ) T=log_2(n) T=log2(n)
我们构造一个满足 T = l o g 2 ( n ) T=log_2(n) T=log2(n)的方案即可。
细菌每天增加的个数最大为 已有细菌的个数*2,但是很容易超过 n n n而不是恰好等于 n n n,下面想办法让细菌的天数能恰好等于n。
细菌增加的个数取 m i n = ( 还 需 要 的 权 值 能 增 加 的 次 数 , 2 j ) min=(\frac{还需要的权值}{能增加的次数},2j) min=(,2j)

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF  = 0x3f3f3f3f;
const ll  mod  = 1e9 + 7;
const ll  maxn = 1e6 + 5;
const int N = 30 + 5;

void solve(){
	int n;cin>>n;
	int ans=log2(n);
	cout<<ans<<'\n';
	for(int i=0,j=1;i<ans;i++){//j为细菌的个数
		n-=j;//n表示还需要多少个权值
		int k=min(n/(ans-i),2*j);//细菌堆数最少要几个
		cout<<k-j<<" \n"[i==ans-1];//增加的权值为k,总的细菌个数为k,然而其中有j部分为就算不分裂也会产生的已有细菌个数
		j=k;//更新已有细菌个数
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;cin>>T;
	while(T--){
		solve();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值