zoukankan      html  css  js  c++  java
  • 如何移动最少次数的三色旗

    题目描述:

    三色旗的问题最早由 E.W.Dijkstra 所提出,他所使用的用语为「Dutch Nation Flag」(他是荷兰人),而多数的作者则使用「Three-Color Flag」来称之。
    假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,现在希望将之分类,并排列为蓝、白、红的顺序,要如何移动才能让次数最少?注意只能在绳子上进行这个动作,而且一次只能调换两个旗子。示意图如下:

    分析与解答:

    在一条绳子上移动,也就意味着在程序中只能使用一个阵列,不能使用辅助存储。问题的解法很简单,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移。如果要让移动次数最少的话,还需要一些技巧:
    算法的主要思路为就是用三个下标 b、w、r 分别指向不同的旗子。其中 b 指向的从 0 开始连续排列的蓝色旗子的最后面的第一个非蓝色旗子,r 指向的从最后一个序号开始连续排列的红色旗子的第一非红色旗子。例如:bbrwbbrr,那么 b 指向的就是序号为 2 的红色旗子,r 指向的就是序号为倒数第三的蓝色旗子。
    w 作为可移动的指针来指引旗子的移动,当 w 指向的旗子是白色旗子的时候,w 继续向前移动;当 w 指向的旗子是蓝色的时候,就需要把 b 所指的旗子和 w 所指的蓝色旗子交互;同理当 w 指的旗子是红色的时候就需要 w 所指的红色旗子和 r 所指的旗子交换。
    实现代码如下:

    <?php
    define("BLUE",'b');
    define("WHITE", 'w');
    define("RED",'r');
    
    function swap($x, $y, &$color){
        $temp = $color[$x];
        $color[$x] = $color[$y];
        $color[$y] = $temp;
    }
    
    $color = ['r', 'b', 'r', 'w', 'r', 'r', 'w', 'b', 'b', 'r'];
    $wFlag = 0;
    $bFlag = 0;
    
    $rFlag = count($color) - 1;
    
    echo "旗子开始的排序:";
    for($i=0;$i<$rFlag;$i++){
        echo $color[$i];
    }
    echo "
    ";
    
    while($wFlag<=$rFlag){
        if($color[$wFlag] == WHITE){
            $wFlag++;
        }elseif ($color[$wFlag] == BLUE){
            swap($bFlag, $wFlag, $color);
            $bFlag++;
            $wFlag++;
        }else{
            while ($wFlag < $rFlag&& $color[$rFlag] == RED){
                $rFlag--;
            }
            swap($rFlag,$wFlag,$color);
            $rFlag--;
        }
    }
    
    echo "排序后的旗子";
    for($i=0;$i<count($color);$i++){
        echo $color[$i];
    }
    echo "
    ";
    

    程序的运行结果为

    旗子开始的排序:rbrwrrwbb
    排序后的旗子bbbwwrrrrr
    
  • 相关阅读:
    ExtJS4 Panel中嵌套PDF
    从 JavaScript 数组去重谈性能优化(转)
    js中top、parent、frame
    “N”在Sql Server字段类型中的重要性 (转)
    IE下lineheight的BUG解决 (转)
    ExtJS4 Dialog
    Chrome启动后打开第一个网页很慢的解决方案(转)
    ExtJS4 Grid改变单元格背景颜色
    form表单
    Detect IFrame Load Event 探索Iframe的加载事件
  • 原文地址:https://www.cnblogs.com/hardy-wang/p/13023160.html
Copyright © 2011-2022 走看看