【HNOI2006】鬼谷子的钱袋

本题在洛谷上的链接:https://www.luogu.org/problemnew/solution/P2320


 

做法和二进制划分很像,,,原来我的二进制划分一直有点问题(之前我是枚举2的n次方然后减,逃)。。。

我们举20这个例子,假如我们要表示20以内的数,那么一定要取10,然后再表示出1到10之内的数,加上10也就表示出了11到20之内的数。同理,不断往下推,我们发现将m不断二分,每次得到的结果一定可以表示m以内的数,还可以使得用来表示的数最少,大约是log(m)。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int a[35],cnt;
 5 int main() {
 6     int n;
 7     scanf("%d",&n);
 8     while(n) {
 9         a[++cnt]=n%2==0?n/2:n/2+1;
10         n/=2;
11     }
12     printf("%d\n",cnt);
13     sort(a+1,a+cnt+1);
14     for(int i=1;i<=cnt;++i) {
15         if(i!=1) putchar(' ');
16         printf("%d",a[i]);
17     }
18     return 0;
19 }
AC代码

 

posted @ 2018-10-02 18:44  Mr^Kevin  阅读(108)  评论(0编辑  收藏  举报