奶油沼泽拼图中的小精灵

Posted

技术标签:

【中文标题】奶油沼泽拼图中的小精灵【英文标题】:Pixies in the custard swamp puzzle 【发布时间】:2010-10-28 00:32:45 【问题描述】:

(感谢 Rich Bradshaw)

我正在为以下谜题寻找最佳策略。

作为新的仙王,你有责任绘制王国的奶油沼泽地图。 沼泽被空灵的薄雾覆盖,蛋奶沙司散落在各处。 您可以将您的小精灵送过沼泽,并附有在每个点飞低或飞高的指示。 如果小精灵从蛋奶冻上俯冲下来,它会分心,不会完成它的序列。 由于雾气很浓,你只知道小精灵是否到达了另一边。

在编码方面..

bool flutter( bool[size] swoop_map ); 

这将返回小精灵是否在给定的猛扑序列中退出。

最简单的方法是一次性传递序列。这揭示了“大小”尝试中的所有蛋奶冻岛。 我更喜欢与蛋奶冻的数量成正比的东西 - 但对以下序列有问题:

     C......C     (that is, custards at beginning and end) 

也欢迎提供其他形式的这个谜题的链接。

【问题讨论】:

这些出击是自适应的还是非自适应的?也就是说,后期小精灵的飞行计划能否依赖于早期小精灵的结果?此外,在低端,您可以期望的最好结果是 log_2(size) 次出击以找到一个蛋奶冻。 是的,如果可以减少总数,鼓励自适应出击。 【参考方案1】:

这让我想到了分而治之。可能是这样的(这是稍微损坏的伪代码。它可能有栅栏错误等):

retval[size] check()

   bool[size] retval = ALLFALSE;
   bool[size] flut1 = ALLFALSE;
   bool[size] flut2 = ALLFALSE;
   for (int i = 0; i < size/2; ++i) flut1[i] = TRUE;
   for (int i = size/2; i < size; ++i) flut2[i] = TRUE;
   if (flutter(flut1)) retval[0..size/2] = <recurse>check
   if (flutter(flut2)) retval[size/2..size] = <recurse>check

在简单的英语中,它在 custard 地图的每一半上调用颤振。如果任何一半返回 false,则整个一半没有奶油冻。否则,一半的一半具有递归应用的算法。我不确定是否可以做得更好。但是,如果沼泽大部分是奶油冻,这个算法就有点蹩脚了。

想法二:

int itsize = 1
bool[size] retval = ALLFALSE;
for (int pos = 0; pos < size;)

    bool[size] nextval = ALLFALSE;
    for (int pos2 = pos; pos2 < pos + size && pos2 < size; ++pos2) nextval[pos2] = true;
    bool flut = flutter(nextval)
    if (!flut || itsize == 1)
    
        for (int pos2 = pos; pos2 < pos + size && pos2 < size; ++pos2) retval[pos2] = flut;
        pos+=itsize;
    
    if (flut) itsize = 1;
    if (!flut) itsize*=2;

用简单的英语,它在 custard map 的每个元素上调用 flutter,一次一个。如果它没有找到 custard,下一次调用的元素数量将是上一次调用的两倍。这有点像二分搜索,除了只在一个方向上,因为它不知道它正在搜索多少个项目。我不知道这有多有效。

【讨论】:

好吧,我添加了一个更容易分析的变体,可能值得以更简单的方式重写。 分成3个来处理“哨兵”案件(一个在开头和结尾)会有什么好处吗? 算法#1终于得到了正确的分析——一点都不蹩脚。 咖啡师:不是。在“哨兵”情况下,您仍然只花费 O(log(N)) 时间。除以 3 使“哨兵”案例 O(1),但代价是处理一个特定案例的愚蠢小技巧。 +1 致 Brian:您可以通过多种方式提高最佳情况下的性能,但最坏情况下的提高不会超过一个常数因素。【参考方案2】:

Brian 的第一个分治算法在以下意义上是最优的:存在一个常数 C,使得在所有具有 n 个正方形和最多 k 个蛋羹的沼泽中,没有算法的最坏情况比 Brian 的算法好 C 倍以上. Brian 的算法使用 O(k log(n/k)) 航班,这是在一个常数因子内 log2(n 选择 k) >= log2((n/k)^k) = k Omega( k 对数(n/k))。 (您需要像 k

为什么布赖恩的算法只使用 O(k log(n/k)) 次飞行?在递归深度 i,它最多进行 min(2^i, k) 次飞行。 0

【讨论】:

以上是关于奶油沼泽拼图中的小精灵的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV - 滑动拼图验证码自动识别与匹配

ROS2机器人实验报告提示02➡沼泽⬅

ROS2机器人实验报告提示02➡沼泽⬅

ABC拼图约束满足问题

Java小项目之拼图游戏

我应该如何为精灵表中的精灵分配名称?