#include<stdio.h>
typedef struct Node
{
}node;
int main()
{
}
1.第一种方法:
分析:设一个包括m个元素的数组,初始值将数组的每个元素放1。从第一个元素开始,
依次取数组元素相加,当其和为n 时,输出该元素的下标(它即是应该出圈人的编号)。然
后将该元素清0,使以后相加时不再起作用,相当于该人已出圈。再从下一个元素开始,依
次取数组元素相加,当其和为n 时,再输出该元素的下标,如此继续,直到输出m 个值以
后结束。
2. 第二种方法
分析用循环链表解决问题,首先需要构造一个循环链表,构造循环链表的方法很简单,
只要将最后一个人的下一个指针指向第一个人,这样就构成一个环,如图所示,构造循环链
表以后,就可以进行删除操作,直到循环链表剩下一个人为止。
3.第三种方法
根据方法二的联想,可以通过数组元素的值是下一数组元素的下标构成环,再利用数组
下标还是数组把前一元素跳过该元素与再下一个元素相连,不再访问已出圈的元素,从而加
快速度。
设一个包括m个元素的数组,在每个数组元素中存放与其相连的下一个元素的编号。
当某人出圈时,将对应元素的值放入前一元素中,使得前一元素跳过该元素与再下一元素相
连,因而再也不会访问已出圈的元素了。以5 个人围成一圈为例,开始数组a 按如下形式存
放数据:
数组元素 A[1] A[2] A[3] A[4] A[5]
数据 2 3 4 5 1
当第3 个人出圈时,将元素a[3]的值4 送入a[2]中,使得元素a[2]直接和元素a[4]相连。
4.第四种方法
让我们进一步思考,能否利用数学知识,归纳递推公式。例如5 人按3 报数的情况,
可以得到出圈的先后序列:3,1,5,2,4,在这里最后一个出圈者编号为4,实际上第一
个出圈的人(编号3)出圈以后,把编号4和5 上移一个元素,可以看作是剩余的4 个人继
续按3 报数了,把剩余的4 人再按上述处理,这样最后一个出圈者编号在位置1 中。
推广到一般情况,即共有m个人从第s人开始报数,按n报数的情况,当剩余I个人的
时候,第s 编号的人出圈以后,对后面元素上移一个元素,归纳出圈者编号的递推公式:s(出
圈编号)=(s+n-1) mod I。举例:共有16 人,从第1 人开始报数,按8报数的情况,按上述递
推公式计算,第一个出圈者的编号为s=(1+8-1)mod 16得8,剩余15(即I=15)人,继续计
算第二个出圈者的编号为s=(8+8-1) mod 15 得0, 此时为特例,当s=0 时,出圈编号正好既
是报数的倍数又是末尾一个编号(当s=0 时,s=I 即编号为15 的人出圈),…最后一个出圈
者编号在位置1 中。