首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現螞蟻爬桿問題:最小/最大離開時間計算

     編輯:PHP 綜合知識

經典的「螞蟻爬桿」問題:一根 27 公分細桿,五隻螞蟻分別位於 3、7、11、17、23 公分處。螞蟻初始朝向隨機,相遇即掉頭,速度 1 cm/s。求所有螞蟻離開桿子的最小與最大時間。本文提供完整 PHP 實現,採用窮舉所有朝向組合(25=32 種)並模擬碰撞邏輯。

核心算法思路

  1. 狀態表示: 位置陣列 $positionArr + 朝向陣列 $directionArr(0=左,1=右)。
  2. 窮舉朝向: 遞歸函數 add2() 生成 0~31 的二進制組合,映射為五隻螞蟻的朝向。
  3. 逐秒模擬: calculate() 循環推進時間,每秒更新位置,檢測碰撞(位置重合)並反轉朝向,移除離開邊界(0 或 27)的螞蟻。
  4. 統計結果: 記錄每種初始朝向下的總耗時,最終排序得出最小/最大值。

完整可運行代碼

<?php
/** 螞蟻爬桿模擬器 */
function add2($directionArr, $count, $i) {
    if (0 > $i) return $directionArr;
    if (0 == $directionArr[$i]) {
        $directionArr[$i] = 1;
        return $directionArr;
    }
    $directionArr[$i] = 0;
    return add2($directionArr, $count, $i - 1); // 進位
}

$positionArr = [3, 7, 11, 17, 23];
$rodLength = 27;

function path($positionArr) {
    global $rodLength;
    $count = count($positionArr);
    $directionArr = array_fill(0, $count, 0);
    $end = str_repeat('1', $count);
    $pathCalculate = [];

    while (true) {
        $pathKey = 'P' . implode('', $directionArr);
        $pathCalculate[$pathKey] = calculate($positionArr, $directionArr, $rodLength);
        if ($end == implode('', $directionArr)) break;
        $directionArr = add2($directionArr, $count, $count - 1);
    }
    return $pathCalculate;
}

function calculate($positionArr, $directionArr, $rodLength) {
    $total = 0;
    $pos = $positionArr;
    $dir = $directionArr;

    while ($pos) {
        $total++;
        $next = [];
        // 1. 所有螞蟻前進一步
        foreach ($pos as $id => $p) {
            $next[$id] = (0 == $dir[$id]) ? $p - 1 : $p + 1;
        }
        // 2. 移除離開邊界的螞蟻
        foreach ($next as $id => $p) {
            if ($p <= 0 || $p >= $rodLength) unset($next[$id]);
        }
        // 3. 碰撞檢測:位置相同者反向
        $posCount = array_count_values($next);
        foreach ($posCount as $position => $cnt) {
            if ($cnt >= 2) {
                foreach ($next as $id => $p) {
                    if ($p == $position) $dir[$id] = 1 - $dir[$id];
                }
            }
        }
        $pos = $next;
    }
    return $total;
}

$results = path($positionArr);
asort($results);
echo "最小時間: " . array_key_first($results) . " = " . array_shift($results) . " 秒\n";
echo "最大時間: " . array_key_last($results) . " = " . array_pop($results) . " 秒\n";
echo "\n全部組合耗時:\n";
print_r($results);

運行結果與分析

最小時間: P00000 = 3 秒   // 全部向左,最近螞蟻在 3cm 處
最大時間: P11111 = 24 秒  // 全部向右,最遠螞蟻在 23cm 處,需走 4cm 到 27cm

物理直覺驗證: 螞蟻碰撞掉頭等價於「穿過彼此繼續前進」(螞蟻不可區分)。因此最小時間 = 最近螞蟻到最近端距離 = 3s;最大時間 = 最遠螞蟻到最遠端距離 = 27-3 = 24s。模擬結果與理論完全吻合。

代碼優化方向

  • 數學解法: 直接計算 min(max(pos, L-pos)) 與 max(max(pos, L-pos)),O(n) 解決,無需模擬。
  • 擴展性: 支援任意桿長、任意螞蟻數量、不同速度、雙向輸出軌跡動畫。
  • 可視化: 結合 HTML5 Canvas 繪製實時動畫,作為教學演示工具。

這個例子展示了如何用 PHP 將經典算法問題轉化為可運行、可驗證的代碼,適合算法入門練習與面試準備。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved