本题在洛谷上的链接: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 ",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 }