约瑟夫环解法

最后更新于:2022-04-01 21:40:24

### 问题描述 设有n个人围坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数, 报数到第m个人, 此人出圈, 再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止。现要求按出圈次序,给出这n个人的顺序表p。请考生编制函数Josegh()实现此功能并调用函数WriteDat()把编号按照出圈的顺序输出到OUT.DAT文件中。设 n = 100, s = 1, m = 10进行编程。 ### 解析 约瑟夫环有好多种解法,但是大体的可以分为两类:1. 将符合出圈要求的人进行标注,但是不出圈,只是下次再轮到此人时,直接跳过,不参加报数2. 将符合出圈要求的人直接出圈(从环中删除),剩下的人继续报数。这里列的是第二种方法,删除的方法是把该元素放到数组中的最后一个位置上,在出圈元素的后边的元素,都向前移动一位。 ### 实现如下: ~~~ void Josegh(void) { int i; int count;//count当做数数的变量 int people=n;//定义没有出圈的人数 int tem;//存放出圈人的编号 int j; //为这100个人进行编号 for(i=0;i1) { i=i%people;//已经出圈人的下标不再计算之内,也就是说数到数组中最后一个没有出圈的编号的时候,i重新指向0 count=count%m;//count数到9的时候再从零开始数 //count数到10的时候count的值为0,执行下面的if语句 if(count==0){ //下面的循环将出圈的人之后的编号往前移动一位,出圈的人的编号放在p数组中的最后一位,视为出圈,同时人数减少一个 tem=p[i]; for(j=i;j ';