D. Phoenix and Science

D. Phoenix and Science

題意
剛開始有一個細菌質量是1,然後從第一天開始,白天你可以選擇讓任意個細菌分裂,質量爲m的細菌可以分裂爲兩個質量爲m / 2的細菌,到了每天晚上每個細菌的質量都會加1,問最少要多少天,細菌的質量總和恰好可以達到n,輸出每天分裂的細菌的個數。

思路
這是一個構造題。構造的方法應該挺多的。
考慮一下,對於細菌分裂而言,只是個數增加了,總質量是不變的,那麼質量是怎麼增加的呢?靠每天晚上的所有細菌的質量自增一。很容易知道,如果當前細菌的總個數爲x,那麼經過一天後,質量的增量爲
[x,2x],爲什麼?如果白天不分裂,晚上自增質量就是x,如果白天都分裂,x個細菌變爲2x個細菌,那麼晚上2x細菌每個都質量加1。所以既然要快速得到總質量爲n,我們考慮讓細菌每天都一直分裂。
那麼總質量就是sum=1+2+4+8+16…把每個數字加入數組中,我們計算出離n最近的總質量。
比如n爲8,我們得到1+2+4=7,還少1怎麼辦呢,把n-sum也加入數組。
排序一下。數組中的每個ai的含義是,到第i天爲止,有i個細菌。
那麼差分輸出一下即可。差分得到就是每天新增的細菌數,也就是分裂的個數

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        vector<int> a;
        int sum=0;
        for(int i=1;sum+i<=n;i<<=1){
            sum+=i;
            a.push_back(i);
        }
        if(sum<n) a.push_back(n-sum);
        sort(a.begin(),a.end());
        cout<<a.size()-1<<endl;
        for(int i=1;i<a.size();i++){
            cout<<a[i]-a[i-1]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章