【解题思路】本题要求报数出圈问题中出圈人的编号次序。依照题意,数组p[100]代表初始时的100个位置,此时给p[100]中的100个元素依次赋值为从1到100的数,以表示在这100个位置处的人,即数组下标代表位置(范围为0~99),数组元素的数值即是在此位置的人的编号(范围为1~100)。然后开始报数出圈操作,这里变量i表示还剩下的未报数的人数同时也是剩下的圈的周长,初始时是n(本题中n取100),s表示当前报数1的人的位置,因为圈的第一个位置的人第一个报数,对应p[0],所以s=0,m表示报数到何位置的人出圈。不考虑报数范围超出到圈的末尾的情况,即相当于报数的人排一条直线的情况下,s位置的人报数1后,报数m而出圈的人的位置应该是s+m-1,考虑报数到圈的末尾要回到第一个位置继续的情况,则应为(s+m-1)%i,即报数位置达到圈长i的时候,从头开始报数,该位置的人报数出圈后,下一个位置的人前移到此位置并在下一轮开始后报数1,因此将(s+m-1)%i赋值给s,表示这一轮出圈和下一轮报数1的人的位置,并将出圈的人的编号暂存到变量temp中。将从s位置至圈尾的所有人前移一位(人的移动用赋值来实现,即p[j]=p[j+1]),而出圈的人移动到原先的圈尾位置,同时圈长i减1。该操作可以认为是报数m的人出圈,其后的人向前挪一位,圈尾多出来的位置也出圈后排到之前出圈的位置之前,出圈的人再移动到出圈的位置,圈的长度减1。循环进行该操作,其效果是,出圈的人依次移动到从圈尾起的位置,直至只剩下一个人为止,最终按出圈的相反顺序排成一列。注意本题中的WriteDat()函数是倒序输出的,因此不需要再调整次序。
【参考答案】 voidJosegh(void)
{ inti,j,temp; /* 定义变量 */ for(i=0;ifor(i=n;i>=2;i--) /* 依次出圈 */ { s=(s+m-1)%i; temp=p[s];for(j=s;j