### 問題描述
設有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數列
- 程序算法藝術與實踐:遞歸策略基本的思想
- 程序算法藝術與實踐:經典排序算法之插入排序
- 程序算法藝術與實踐:遞歸策略之遞歸,循環與迭代