问题:N个人围成一环形圈,第一个人从1开始报数,报道M的人出列,直到最后一个同学并输出
分析:N个人保存在大小为N的数组中,索引为0的人员从1开始报数,每报道M的索引被清除,总共清除N-1次,数组最后大小为1既为所求
代码:
<?php
$n=10;//N个人
$m=3;//M值
$arr = array();
for($i=0;$i<$n;++$i){
$arr[$i] = 1;
}
$i = $m-1;//第一个出局索引
echo get_last_index($arr, $i,$m, $n);
/**
* 获取最后一个人员的数组索引
* @params array $arr 标识人员的数组,初始为所有人员
* @params int $i 第一个出局人员的索引
* @params int $m 每隔开$m人员淘汰
* @params int $n 人员总数
* @return int 最后一个人员的数组索引
*/
function get_last_index(&$arr, $i,$m, $n){
$c = $n;
while((–$c)>0){
//echo $i.”<br />”;
unset($arr[$i]);
$i=get_out_index($arr,$i,$m,$n);
}
$arr = array_keys($arr);
return $arr[0];
}
/**
* 获取报道为M的人员的数组索引
* @params array $arr 标识人员的数组,初始为所有人员
* @params int $i 第一个出局人员的索引
* @params int $m 每隔开$m人员淘汰
* @params int $n 人员总数
* @return int 报道为M的人员的数组索引
*/
function get_out_index(&$arr,$i,$m,$n){
while($m>0){
$i = ($i+1)%$n;
if(isset($arr[$i])){
–$m;
}
}
return $i;
}
?>
测试数据:
N=10,M=3则输出3
N=10,M=2则输出4
N=20,M=3则输出19
N=30,M=4则输出5
随便手工测试了几个数据,因为时间关系没有找到现成的数据测试所以只测试了少数数据,如果发现有疑问请拍砖!