丢手帕问题即约瑟夫问题的PHP解法

问题描述:n个人排成一圈。从某个人开始,依次报数,数到m的人被杀死。下一个人重新从1开始报数,数到m的人被杀死。直到剩下最后一个人。

解决思路:从数学角度去看,每一次报数决定谁去死是一个n、m的求余数过程。从程序角度看,玩家和编号一一对应,每一次报数玩家减少一个,编号重新排列。

程序:

1.首先声明相关变量

$childAmount = 6; //总人数
$endNumber = rand(1,6); //死亡编号取随机值
$gameNumber = 0;//游戏次数
$childArray = array('a','b','c','d','e','f');//玩家姓名数组
$playArray = array();//编号姓名对应关系数组
$killArray = array();//死亡顺序名单数组
//初始化
shuffle($childArray);//取随机排序

2.游戏开始前数组准备

//初始化
shuffle($childArray);//取随机排序
//构建关联数组
for($i=0;$i<count($childArray);$i++){
        $playArray[$i+1] = $childArray[$i];
}
echo '<pre>';
echo "玩家数:".$childAmount."死亡编号:".$endNumber."<br>";
echo "这是初始游戏编号:";
print_r($playArray);
echo '</pre>';

3.游戏开始

//死亡循环
while($childAmount > 1){//判断人数是否大于1,决定游戏是否结束
    $number = $endNumber % $childAmount;//求取余数
    //当余数为0时,死亡的是编号最大的人
    if($number == 0){
        $killArray[] = $playArray[$childAmount];//加入死亡名单
        unset($playArray[$childAmount]);//该玩家死亡
        $childAmount -= 1;//游戏人数减一
        $gameNumber += 1;//死亡循环次数加一
    }else{//余数不为0,死亡的是编号等于余数的人
        $temp = array();
        $killArray[] = $playArray[$number];
        unset($playArray[$number]);
        //规律:余数不为0,大于以及小于该余数的编号之后的人编号从1开始重新排列。大于该编号的人编号为(本身编号-死亡编号),小于该编号的人编号为(本身编号+当前最大编号-死亡编号)
        foreach($playArray as $key => $value){
            if($key > $number){    
                $temp[$key-$number] = $value;
            }else{
                $temp[$key+$childAmount-$number] = $value;
            }
        }
        ksort($temp);//按键名排序
        $playArray = $temp;
        $childAmount -= 1;
        $gameNumber += 1;
    }
    if($childAmount == 1){
        echo '<pre>';
        echo '幸存者是:';
        print_r($playArray);
        echo '</pre>';
        
    }
}
echo '<pre>';
echo "死亡顺序:";
print_r($killArray);
echo '</pre>';

 

转载于:https://www.cnblogs.com/duogu-wjm/p/6211544.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值