【答案】
void Josegh(void)
{
int i,j; /*定义循环控制变量*/
int s1,w; /*存储开始报数的人的编号*/
s1=s; /*第一个报数的人的编号*/
for(i=1;i<=n;i++) /*给n个人从1到n编号*/
p[i-1]=i;
for(i=n;i>=2;i--) /*当人数少于2时,停止报数*/
{
s1=(s1+m-1)%i; /*下一个开始报数的人的编号是(s1+m-1)%i*/
if(s1==0) /*若s1为0,则说明要开始报数的是最后一个人*/
s1=i;
w=p[s1-1]; /*将要出圈的人移至数组的最后*/
for(j=s1;j<=i-1;j++)
p[j-1]=p[j];
p[i-1]=w;
}
}
【解析】此题是著名的"约瑟夫环"问题。首先要将每个人的编号存入数组。因为每次是从s1开始报数,若是直线队则下一个开始报数的人的编号是s1+m-1,但这里要建立一个环,即最后一个人报完数后第一个人接着报数。所以这时下一个开始报数的人的编号是(s1+m-1)%i,i是此时圈中的总人数。若所得的结果为0,则说明要开始报数的是最后一个人。在此人前面的那个人就是要出圈的人,使用循环将要出圈的人移至数组的最后。开始时,总人数为n,以后依次减1,直到最后一个人出圈。