分石子(思维题 & 二进制)

Description

有n个石子,将它分成k堆,对于[1,n]的任意一个数,都能用某几堆石子组成(每一堆只能用一次),求k的最小值。

Input

多组样例输入输出,输入n(1=<n<=1e18)

Output

每个测试样例输出k,占一行,k的含义如题目所述

Sample Input 1

6
2
1
Sample Output 1

3
2
1
Hint

分成的任意两个石子堆中石子个数可以是相同的。

以前这个题目不理解,但是后来有人问这个,我思考了一下然后来补充一下:所有数字都是可以用二进制表示的,所以,我们假设一个数字n,用二进制表示为k位。那么小于等于n的数,位数一定小于等于k。并且n 大于一共 k-1 位二进制数(每一位都是1)。那么,我们就不断的将这个n进行划分,每一部分(除最后一部分外)都是2的幂的形式,也就是,先把一个 k -1 位的二进制数的每一位都填上一,直到最后第k位没法填充为止,这样就正好分成了k堆。那么,从1到n。不管是哪个数,用二进制表示出来,取相应位置的那一堆石子就可以了。

比如:6 = 110,那么我们先填最低位,就是001, 然后剩了5,再填第二位,也就是010,这样剩下3,要填最高位,但是最高位是4, 3 < 4,填不上,那么3就自己一组,011.这样就直接算一个数的二进制位数就可以了。

AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;

int main()
{
    ll n;
    while(~scanf("%lld", &n))
    {
        ll ans = 0;
        while(n)
        {
            n >>= 1;
            ans++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值