扔玻璃球问题

本文探讨了一个有趣的问题:利用三个水晶球确定一栋N层大楼中使水晶球破碎的临界楼层K,目标是最小化最坏情况下的测试次数。文章首先介绍了问题背景及目标,随后通过分析两个水晶球的情况推导出最优策略,并最终给出了解决三个水晶球问题的具体算法及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Homework of Physics


Physics teacher gives Nobita three crystal balls, and asks Nobita to finish a homework.
There are a building of N floors,
Nobita should use these three crystal balls to get the critical value of crystal ball to be breaked.
That is find the number K, the crystal ball will not be breaked if it's thrown in the Kth floor,
but the crystal ball will be breaked if it's thrown in the (K+1)th floor.
So Nobita need to find a policy to do experiment to get the value K,
and make the number of tries in the worst situation to be minimum.


Note: If the crystal ball is breaked, it can't be used again.
Note: The crystal may be breaked in the first floor, or not be breaked in the Nth floor.


Input


The first line contains an integer T, indicates the number of test case.
For each test case,
Contain a integer N, indicates the number of floors in this building.
(1<=N<=10^15)


Output


For each test case, output one line.
Contain an integer means the critical value K.


Sample Input


3
1
2
3


Sample Output


1
2

2

题意:给定三个玻璃球,还有一幢n层高的楼,玻璃球在k层之前丢下不会碎,之后丢下会碎,碎了就不能再用了。问最坏情况要测多少次。

题解:先考虑二个玻璃球的情况,最坏情况,因为k是不确定的,于是可以这样想,如果没丢一层楼,就会有两种情况,那么就可以建立一个二叉树,那么最坏情况是什么时候呢?就是树最深的深度。所以,为了取最优情况,就应该使得无论选择出现怎样的情况,都是一样的测试次数。于是可以想到,先假设测量次数为t,那么第一次丢应该在t层楼丢,如果碎了,就从第一层丢到t-1层,得到结果,如果没碎,则在2*t-1上丢,这样测试t次能达到的最大楼层高度为(t+1)*t/2。

然后考虑三个玻璃球,用刚才的思想,由于多出一个玻璃球,那么分出1、2、3.....t-1次测试在第一个玻璃球上,如果碎掉,则在该次测试楼层以下进行二个玻璃球的测试。于是答案变成求(n)∑(i=1) (i+1)*i/2。可以得到公式:((2*n-1)*n*(n-1)/6-n*(n-1)/2)/2+n。

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll n;

ll work(ll n)
{
    return ((2*n-1)*n*(n-1)/6-n*(n-1)/2)/2+n;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        int l=1,r=1000000;
        while(l+1<r)
        {
            ll mid=l+r>>1;
            if(work(mid)<=n) l=mid;
            else r=mid;
        }
        printf("%d\n",l);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值