然后重新从下一个小孩开始.直到只剩下一个为止.
虽然使用循环链表很方便, 但数组一样可以, 只是算法稍微麻烦一点.
struct Boy{
int num;
bool isOut;
};
Boy boy[NUM]; 定义一个数组, 用isOut表示是否退出
关键的算法如下
for(int t=0;!isOneBoy();){ //isOneBoy()判断是否只剩下一个
/*
下面的循环最容易出错,我调试好半天才弄明白几个地方
1. 数数时要注意:出列的不算.所以 for循环m次,目的是加上m个还在的小孩
2. 每次重新开始数数时也要注意,把出列的排除,即:isOut为true的不算
*/
for(int i=0;i<interval-1;i++){
posiToMove+=1;
while(boy[posiToMove%size].isOut==true){ //出列的不计数
posiToMove++;
}
}
boy[posiToMove%size].isOut=true;
posiToMove+=1; //移到下一个位置, 重新开始数
while(boy[posiToMove%size].isOut==true){ //出列的不计数
posiToMove++;
}
posiToMove%=size;
}
以上就是最麻烦的,其他就简单了, 如判断是否只剩下一个小孩:
bool isOneBoy( ){
bool t=true;
for(int i=0;i<NUM;i++){
if(boy[i].isOut==false){
t=!t;
}
if(boy[i].isOut==false&&t==true){
return false;
}
}
return true;
}
结果: 当10个小孩,开始位置为3, 间隔为3 时, 出列: 5 8 1 4 9 3 10 7 2
最后的剩下的是6