题目描述

[HNOI2006]鬼谷子的钱袋_#include

[HNOI2006]鬼谷子的钱袋_#include_02

输入输出格式

输入格式:

 

[HNOI2006]鬼谷子的钱袋_输入输出_03

输出格式:

[HNOI2006]鬼谷子的钱袋_#include_04

输入输出样例

输入样例#1:
3
输出样例#1:
2
1  2
题解:
因为任何一个数都能表示为2^X的和
所以要构成1~m内的金币数,只需把m二进制分解
把m分解为2^0+2^1+2^2....+2^p+k(剩余的金币)
有一个坑:剩余金币为k=2^x时,要把2^p-1,再把k+1.
钱袋数直接输出log2m+1就行了
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int m,a[10001];
 8 int main()
 9 {
10     cin>>m;
11     cout<<(int)log2(m)+1<<endl;
12     int k=0,x=1,sum=0;
13     while (sum+x<=m)
14     {    
15         k++;
16         a[k]=x;
17         sum+=x;
18         x*=2;
19     }
20     x=m-sum;
21     int b=0;
22     if (x)
23 for (int i=1;i<=k;i++)
24 if (a[i]==x) 
25 {
26     a[k]--;
27     k++;
28     a[k]=x+1;
29     b=1;
30     break;
31 }
32 if (!b&&x) k++,a[k]=x;
33 for (int i=1;i<=k;i++)
34 printf("%d ",a[i]);
35 }