LuoguP2320/CF1037A 用二进制表示数的奥妙重重方法 By cellur925
题目描述
鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政。
有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一件宝物引起了他极大的兴趣,那就是无字天书。
但是,他的行程安排得很满,他已经买好了去邯郸的长途马车票,不巧的是出发时间是在拍卖会快要结束的时候。于是,他决定事先做好准备,将自己的金币数好并用一个个的小钱袋装好,以便在他现有金币的支付能力下,任何数目的金币他都能用这些封闭好的小钱的组合来付账。
鬼谷子也是一个非常节俭的人,他想方设法使自己在满足上述要求的前提下,所用的钱袋数最少,并且不有两个钱袋装有相同的大于1的金币数。假设他有m个金币,你能猜到他会用多少个钱袋,并且每个钱袋装多少个金币吗?
我们可以知道,用二进制(二的几次幂)可以表示一定范围内的所有数。或者用dalao的话说,用分治的思想,表示n以内的任何数字可以用1到n/2内的数字,那么表示n/2以内的任何数字可以用1到n/4以内的数字……
于是钱袋数就是log2(n)+1;(要上界所以加1)
1 #include<cmath> 2 #include<cstdio> 3 4 using namespace std; 5 6 int n; 7 8 int main() 9 { 10 scanf("%d",&n); 11 printf("%d",(int)log2(n)+1); 12 return 0; 13 }
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<iostream> 5 6 using namespace std; 7 typedef long long ll; 8 ll k; 9 ll cnt,tot; 10 int a[10000]; 11 double ans; 12 13 int main() 14 { 15 scanf("%lld",&k); 16 ans=(double)log2(k+1); 17 ans=ceil(ans); 18 printf("%.0lf\n",ans); 19 cnt=(ll)ans; 20 while(cnt--) 21 { 22 k%2==0 ? a[++tot]=k/2 : a[++tot]=(k+1)/2; 23 k/=2; 24 } 25 sort(a+1,a+tot+1); 26 for(int i=1;i<=tot;i++) printf("%d ",a[i]); 27 return 0; 28 }
独立意志与自由思想是必须争的,且须以生死力争。