拿到这个我就在思考这个怎么做,但是看到参考程序跟我思考的不太一样,但是结果是一样的。
分析:当你和你的n个朋友在最后一起的时候就不需要自杀,所以只有你们自己人留在最后才可以保全所有人。,所以你要找到自杀的顺序,把自己想要救的人留在最后自杀的顺序上,那样就可以避免自杀。
我看到这个我就会想起约瑟夫问题,那么我就可以用约瑟夫方法来解决问题就好了,约瑟夫问题就是留下一个人,而这里却是留下多个人,可以用array_push来解决这个问题
上代码吧
<?php
//方法一
function a($n,$m,$t){
$arr=range(1,$n);
$i=0;
while(count($arr)>$t){
if(($i+1)%$m==0){
unset($arr[$i]);
}else{
array_push($arr,$arr[$i]);
unset($arr[$i]);
}
$i++;
}
var_dump($arr);
}
$t=a(41,3,3);
那么结果是啥呢
所以当围成一个圆的时候,座位为16,31,35就可以不用自杀了,因为这三个人都是被保护的人。
但是还有别的算法方式
<?php
//方法二
define('N',41);//参与人数
define("M",3);//每逢3自杀
$man=array(0);
$count=1;
$i=0;
$pos=-1;
$alive=3;//想要救的三个人
while($count<=N){
do{
$pos=($pos+1)%N;
if( @$man[$pos] == 0)
$i++;
if( $i == M ){
$i=0;
break;
}
}while(1);
$man[$pos]=$count;
$count++;
}
arsort($man);
$arr=array_slice($man,0,$alive,true);
echo "约瑟夫排列:";
for( $i = 0 ; $i < N ;$i++){
echo "".$man[$i].'-';
}
echo "<br>L表示要救的".$alive."个人要放的位置";
for($i=0; $i<N; $i++){
if(isset($arr[$i]) && $man[$i]===$arr[$i]) echo "L";
else echo "P";
if(($i+1)%5===0) echo "";
}
其实这个算法的结果与我自己思考的一样