Codeforces 1348 D.Phoenix and Science

题目:
一个细菌初始质量为1,每天可以选择分裂其中任意个,分裂后质量均分,每天晚上所有细菌质量+1.找一个方法使得用最少的天数分裂细菌,使最后总质量等于n。输出天数和每天分裂的细菌个数。

用变量temp表示细菌个数,用all表示目标质量,初始temp = 1,all = n - 1. 仔细考虑发现,分裂一个细菌相当于temp + 1, 而且每天all -= temp;每天可以分裂任意个细菌,temp可以扩展为temp~2temp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<fstream>
using namespace std;
#define rep(i, a, n) for(ll i = a; i <= n; ++ i)
#define per(i, a, n) for(ll i = n; i >= a; -- i)
typedef long long ll;
const int N = 3e6 + 105;
const int mod = 998244353;
const double Pi = acos(- 1.0);
const int INF = 0x3f3f3f3f;
const int G = 3, Gi = 332748118;
ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
//

ll T, l, r, n;
ll res[N], cnt;
int main()
{
    scanf("%lld",&T);
    while(T --){
        int flag = 0;
        cnt = 0;
        scanf("%lld",&n);
        ll all = n - 1;
        ll temp = 1;
        while(all){
            if(temp * 4 <= all){
                res[++ cnt] = temp;
                temp *= 2;
                all -= temp;
            }
            else if(temp * 2 < all){
                ll k = all / 2 - temp;
                res[++ cnt] = k;
                temp += k;
                all -= temp;
            }
            else if(temp <= all){
                res[++ cnt] = all - temp;
                all = 0;
            }
            else {
                flag = 1;
                break;
            }
        }
        if(flag) printf("-1\n");
        else{
            printf("%lld\n",cnt);
            for(int i = 1; i <= cnt; ++ i){
                if(i == cnt) printf("%lld\n",res[i]);
                else printf("%lld ",res[i]);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/A-sc/p/12817561.html