<?php
/*
约瑟夫环:
问题:一群猴子排成一圈,按1,2,…….,n依次编号。然后从第一只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,再把它踢出去………………….,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求:输入m,n,输出最后的那个大王的编号。
*/
//递归算法
function killMonkey($monkeys,$m,$current=0)
{
$number = count($monkeys);
$num = 1;//从第一个开始
if ($number == 1) {
return $monkeys[0];
}
else
{
while ($num++ < $m) {//从第一个开始数到第m个
$current++;//从当前位置开始向后累加
$current = $current % $number;//防止越界
}
array_splice($monkeys, $current,1);//移除被数到的那个
return killMonkey($monkeys,$m,$current);//从current位置开始继续向后数
}
}
$arr_data = range(1, 10);
$last_one = killMonkey($arr_data,3);
echo "{$last_one}是猴王\n";
/*
每个猴子出列后,剩下的猴子又组成了另一个子问题。只是他们的编号变化了。第一个出列的猴子肯定是a[1]=m(mod)n(m/n的余数),他除去后剩下的猴子是a[1]+1,a[1]+2,…,n,1,2,…a[1]-2,a[1]-1,对应的新编号是1,2,3…n-1。设此时某个猴子的新编号是i,他原来的编号就是(i+a[1])%n。于是,这便形成了一个递归问题。假如知道了这个子问题(n-1个猴子)的解是x,那么原问题(n个猴子)的解便是:(x+m%n)%n=(x+m)%n。问题的起始条件:如果n=1,那么结果就是1。
*/
function yuesefu($n,$m) {
$r=0;
for($i=2; $i<=$n; $i++) {
$r=($r+$m)%$i;
}
return $r+1;
}
echo yuesefu(10,3)."是猴王\n";
PHP坑之:约瑟夫环
最新推荐文章于 2019-10-22 14:25:51 发布