为两个蛋的特定版本设计算法

时间:2015-07-18 13:07:33

标签: algorithm

鸡蛋下降。假设您有一个N层建筑(楼层1到N)和大量鸡蛋。如果蛋从地板T或更高处掉落而且没有破裂则会破裂。你的目标是制定一个策略来确定T的价值,因为对鸡蛋和投掷的数量有以下限制:

  • 版本0:1个鸡蛋≤Ttosses。
  • 版本1:~1lgN鸡蛋和~1lgN投掷。
  • 第2版:〜lgT蛋和~2lgT投掷
  • 版本3:2个鸡蛋和~2√N投掷。
  • 版本4:2个鸡蛋和≤c√T投掷某些固定常数c。

这是一个求职面试问题,由在线课程算法,第一部分(普林斯顿)提供。我已经知道如何找到2个鸡蛋所需的最小投掷的一般解决方案,我可以理解版本0到版本3。

我的问题是如何为版本4设计算法。即使有提示我也不知道 该课程给出的提示是: 1 + 2 + 3 + ... + t~1 / 2 * t ^ 2。目标是c =2√2。

2 个答案:

答案 0 :(得分:1)

版本4中提示的含义是:

将N分为多个blocks,例如:

  • block 1中的第1层,即block 1中的1层。
  • block 2中的第2和第3层,即block 2中的2个楼层。
  • block 3中的第4,第5和第6,即block 3中的3个楼层。

...

  • m中有block m个楼层。假设这个区块中的楼层T

然后,将鸡蛋从block m的第一层扔到block m的最后一层,找到T

Java代码(中文评论):

`

/ **

* Ex 1.4.24

* EggsDrop问题

* ~2logF投掷, ~logF鸡蛋

* @param N

*       楼层高度

* @param F

*       鸡蛋恰好摔碎的楼层

* @return 程序猜到的楼层数
*/

private static int eggsDrop3(int N, int F) {

    //debug...

    int debugCnt = 0;

    int debugEggs = 0;

    //区块的左端点相对于一楼的offset
    int leftOffset = 0;

    //区块的长度
    int length = 1;

    //result
    int f = 0;

    //初始第一个区块的左右offset都是0, 因为在第一个区块只有一层楼
    while (leftOffset + length <= N) {
        //leftOffset + legth表示当前区块的右端点
        if (leftOffset + length >= F) {
            debugEggs++;
            debugCnt++;
            //从区块左端点开始遍历
            int last = leftOffset + 1;
            while (last++ < F)
                debugCnt++;
            debugEggs++;
            f = last - 1;
            break;
        } 

        debugCnt++;
        leftOffset += length;
        length++;
    }

    o("tosses: " + debugCnt + ", eggs: " + debugEggs);

    return f;
}

`

这是算法第4版的github项目。(中文):

My solutions to Exercise in Algorithms 4th Ed.

答案 1 :(得分:0)

请按以下步骤操作:

从第一层扔掉第一个鸡蛋,然后从第二层,从第四层,从第七层扔掉,依此类推。即连续楼层的差异每步增加一个。

您需要传递T的投掷次数为

n1 = -1/2 + roundup( sqrt(1/4 + 2T) )

然后使用第二个鸡蛋从最后一个检查点到T线性地进行。这将带你n2投掷:

n2 = T - Sum { i from 1 to n1 - 1 } (i)

您会看到n2也是O(sqrt(T))。因此,投标总数n1 + n2位于O(sqrt(T)),这是您想要的。