扔玻璃球问题

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
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>1;
            if(work(mid)<=n) l=mid;
            else r=mid;
        }
        printf("%d\n",l);
    }
    return 0;
}


你可能感兴趣的:(琐碎)