Description
Bob最近想试一下印假钞,因为印刷超过m面值的假钞可能被抓,因此Bob会印刷总面值m元的假钞。对印刷的假钞有以下要求
-
每张假钞的面值都在 1到 m元范围内并且都是整数
可以有任意张1元的假钞,其他面值的假钞任意两张的面值都不同
-
对于 1到 m元的所有整数价值,都可以用假钞中的一部分凑出来
在以上条件下,请问最少印多少假钞能满足要求
Input
包含一个整数m(0≤m≤109)m(0≤m≤109)
Output
两行,第一行一个整数h,表示所印假钞个数
第二行表示每张假钞的面值,由小到大输出,空格隔开
Sample Input
3
Sample Output
2
1 2
解题思路:
二分的思想。以数字8为例,8可以分为4+4,然后4可分为2+2,2可以分为1+1,结束划分,故8可表示为8=4+2+1+1;
同理,以11为例,11可以划分为6+5,5可以划分为3+2,2可以划分为1+1,故11可表示为11=6+3+1+1;画个二叉树也许更好理解......
总结:对于奇数的划分,每次二分向上取整,然后对奇数中还未划分的整数继续以类似的形式划分即可......;对于偶数,直接二分就行了。
#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
int a[10000000];
int main(int argc, char** argv) {
int m;
while(scanf("%d",&m)!=EOF)
{
if(m==0)//特殊情况....
{
printf("0\n");
continue;
}
int cnt=0;
while(m!=1)//结束部分不能再继续二分了,所以是1
{
int x=ceil(m/2.0);//二分且向上取整
a[cnt]=x;
cnt++;
int y=m-x;
m=y;
}
a[cnt]=m;
printf("%d\n",cnt+1);
for(int i=cnt;i>=0;i--)
{
printf("%d ",a[i]);
}
printf("\n");
}
return 0;
}