### 问题描述
设有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;i<n;i++){
p[i]=i+1;
}
i=0;
count=1;//数数的下标从零开始,count从1开始。也就是说以i为下标的编号,正是count所数的编号,count和i是同时增加的。
//在还没有人出圈之前,people=100,每出圈一个人people-1。当只剩下一个人的时候循环停止。
while(people>1) {
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<people-1;j++){
p[j]=p[j+1];
}
p[j]=tem;
people--;
count++;//根据题意,count重新开始数数的位置是当前位置
}
i++;
count++;
}
}
~~~
**转载请注明出处**:[http://blog.csdn.net/utimes/article/details/8762227](http://blog.csdn.net/utimes/article/details/8762227)
- 前言
- 螺旋矩阵、螺旋队列算法
- 程序算法艺术与实践:稀尔排序、冒泡排序和快速排序
- Josephu 问题:数组实现和链表实现
- 杨辉三角形算法
- 位图排序
- 堆排序的实现
- Juggling算法
- 【编程珠玑】排序与位向量
- 取样问题
- 变位词实现
- 随机顺序的随机整数
- 插入排序
- 二分搜索
- 产生不重复的随机数
- 约瑟夫环解法
- 快速排序
- 旋转交换或向量旋转
- 块变换(字符反转)
- 如何优化程序打印出小于100000的素数
- 基本的排序算法原理与实现
- 利用马尔可夫链生成随机文本
- 字典树,后缀树
- B-和B+树
- 程序算法艺术与实践引导
- 程序算法艺术与实践:基础知识之有关算法的基本概念
- 程序算法艺术与实践:经典排序算法之桶排序
- 程序算法艺术与实践:基础知识之函数的渐近的界
- 程序算法艺术与实践:递归策略之矩阵乘法问题
- 程序算法艺术与实践:递归策略之Fibonacci数列
- 程序算法艺术与实践:递归策略基本的思想
- 程序算法艺术与实践:经典排序算法之插入排序
- 程序算法艺术与实践:递归策略之递归,循环与迭代