CF1348 D. Phoenix and Science

CF1348 D. Phoenix and Science

Question

一開始有1個細菌,他的權值爲1。白天的時候1個細菌可以分裂成2個,也可以不分裂,晚上的時候1個細菌會增加權值1,求最少要多少天能夠到達所有權值的和恰好爲n,並且給出對應n天每天有幾個細菌要分裂。

Solution

設需要TT天。
最快的增加方法爲每次所有細菌分裂爲22個,晚上加上分裂後細菌的數量,那麼T=log2(n)T=log_2(n)
我們構造一個滿足T=log2(n)T=log_2(n)的方案即可。
細菌每天增加的個數最大爲 已有細菌的個數*2,但是很容易超過nn而不是恰好等於nn,下面想辦法讓細菌的天數能恰好等於n。
細菌增加的個數取min=(,2j)min=(\frac{還需要的權值}{能增加的次數},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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章