码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces-1348-D Phoenix and Science

时间:2020-05-05 00:46:18      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:分数   数组   def   质量   namespace   答案   com   clean   break   

codeforces-1348-Phoenix and Science

传送门:https://codeforces.com/contest/1348/problem/D

题意:最初有一个质量为1的细胞,白天,任意数量的细胞可以分裂成两半,晚上,每个细胞的质量都会加一,问你多少天能正好让细胞的质量和刚好为N,并输出每天都有多少细胞分裂

 因为细胞分裂质量是不变的,只有晚上质量才会增加,而且还是,当前有多少个细胞,质量就增加多少,把所有天质量的增量+最初的1==n即为所求

因为是分裂,一个变俩,两个变四个,所以他是按2的幂次增长,最少的天数也就指定是每天都尽可能的分裂

然后你这么处理完呢,最后还会剩下一个n-sum 你只要把他填到一个合适的位置然后凑成n就好啦

把他插到我们刚刚处理出来的数据

每天的细胞数量:1 2 4 8 16 n-sum 32  他们的总和就是n,1+2+4+8+16+32=sum(因为他有多少细胞质量就会加多少嘛)

他问每天细胞分裂的个数,你想想,头一天是x,这里面有y个分裂了,分裂之后的细胞个数不就是x+y了吗

所以,预处理出2^k 把n-sum也插进去排序,然后求一个差分数组 就是答案了

以上

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define lowbit(a) ((a)&-(a))
 5 #define clean(a,b) memset(a,b,sizeof(a))
 6 const int mod = 1e9+7;
 7 const int inf=0x3f3f3f3f;
 8 const int maxn = 2e5+10;
 9 int _;
10 /////////////////////////////////////////////////////////////////
11 vector<int>ve;
12 int main()
13 {
14     int t;
15     scanf("%d",&t);
16     while(t--)
17     {
18         ve.clear();
19         int n;
20         scanf("%d",&n);
21         for(int i=0;i<30;i++)
22         {
23             if((1<<i)>n) break;
24             n-=(1<<i);
25             ve.push_back(1<<i);
26         }
27         if(n!=0) ve.push_back(n);
28         sort(ve.begin(),ve.end());
29         printf("%d\n",ve.size()-1);
30         for(int i=1;i<ve.size();i++)
31         {
32             printf("%d ",ve[i]-ve[i-1]);
33         }
34         printf("\n");
35     }
36     return 0;
37 }

 

codeforces-1348-D Phoenix and Science

标签:分数   数组   def   质量   namespace   答案   com   clean   break   

原文地址:https://www.cnblogs.com/YangKun-/p/12828807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!