如何移動最少次數的三色旗

2022-08-12 06:30:34 字數 1227 閱讀 5646

三色旗的問題最早由 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)

$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 "\n";

while($wflag<=$rflag)elseif ($color[$wflag] == blue)else

swap($rflag,$wflag,$color);

$rflag--;

}}echo "排序後的旗子";

for($i=0;$i程式的執行結果為

旗子開始的排序:rbrwrrwbb

排序後的旗子bbbwwrrrrr

三色旗問題

三色旗問題 假設有乙個陣列,它有n個元素,每乙個不外乎是紅,白,藍3種顏色之一的代號,就用r,w,b代表。這些元素在陣列中並沒有依同樣顏色的元素排在一起的方式來排列,請寫乙個程式把這些元素排成所有藍色在前,接著是白色,最後是紅色的排列方式,不過在寫程式時要滿足下面的條件 1 不能用額外的記憶體,換句...

三色旗問題

假設有一根繩子,上面有一些紅 白 藍色的旗子。起初旗子的順序是任意的,現在要求用最少的次數移動這些旗子,使得它們按照藍 白 紅的順序排列。注意只能在繩子上操作,並且一次只能調換兩個旗子。分析 其實要移動旗子得到要求的結果很簡單,但是需要注意的是需要移動最少的次數這個限制條件。網上的一種解法 從繩子開...

三色旗演算法

演算法描述 假設有一條繩子,上面有紅 白 藍三種顏色的旗子,起初繩子上的旗子顏色並沒有順序,您希望將之分類,並排列為藍 白 紅的順序,要如何移動次數才會最少,注意您只能在繩子上進行這個動作,而且一次只能調換兩個旗子。示意圖 解法 在一條繩子上移動,在程式中也就意味只能使用乙個陣列,而不使用其它的陣列...