假设有100个人围成一圈。从人1到人14计数,从圆圈中删除人。按照计数顺序,再次计数并删除第14个人。重复。谁是最后一个站着的人?
我已经尝试了一切来解决这个问题,似乎没有使用死循环。
<?php
//init array
$array = array();
for ($i = 0; $i < 100; $i++) { $array[] = $i; }
//start from 0
$pos = 0;
while (count_not_null($array) > 1) {
//reset count
$count = 0;
while (true) {
//ignore NULL for count, that position is already removed
if ($array[$pos] !== NULL) {
$count++;
if($count == 14) { break; }
}
$pos++;
//go back to beginning, we cant go over 0-99, for 100 elements
if ($pos > 99) { $pos = 0; }
}
echo "set index {$pos} to NULL!" ."<br>";
$array[$pos] = NULL;
if (count_not_null($array) === 1) { break; }
}
echo "<pre>";
print_r($array);
echo "</pre>";
//counting not null elements
function count_not_null($array) {
$count = 0;
for ($i = 0; $i < count($array); $i++) {
if ($array[$i] !== NULL) { $count++; }
}
return $count;
}
?>
答案 0 :(得分:3)
为了用尽可能少的代码来解决这个问题,你可以这样做最快:
function josephus($n,$k){
if($n ==1)
return 1;
else
return (josephus($n-1,$k)+$k-1) % $n+1;
}
echo josephus(100,14);
这里我们使用的是递归语句,因为您要解决的问题可以通过此数学语句f(n,k) = (f(n-1,k) + k) % n
来定义。
有关此数学公式的更多信息,您可以看到它here on the wiki page。
答案 1 :(得分:2)
问题在于循环
while ($count < 14) {
if ($array[$pos] != NULL) {
$count++;
}
$pos++;
if ($pos > 99) { $pos = 0; }
}
因为即使count为14,你也会增加$ pos,你将以不正确的值结束并永远循环。替换为:
while (true) {
if ($array[$pos] != NULL) {
$count++;
if($count == 14) {break;}
}
$pos++;
if ($pos > 99) { $pos = 0; }
}
同样将0与NULL进行比较不会给出@Barmar所提到的预期结果,因此您可以更改NULL比较,或从1开始计数
注意:如果你没有每次循环遍历数组,这会更快:D考虑使用变量来计算剩余的项目