/* 題目要求: 設有n個人圍坐一圈並按順時針方向從1到n編號,從第s個人開始進行1到m的報數, 報數到第m個人, 此人出圈, 再從他的下一個人重新開始1到m的報數,如此進行下 去直到所有的人都出圈為止。現要求按出圈次序,給出這n個人的順序表p。請考生 編制函數Josegh()實現此功能並調用函數WriteDat()把編號按照出圈的順序輸出到OUT.DAT文件中。 設 n = 100, s = 1, m = 10進行編程。 題目解析: 約瑟夫環有好多種解法,但是大體的可以分為兩類: 1. 將符合出圈要求的人進行標注,但是不出圈,只是下次再輪到此人時,直接跳過,不參加報數 2. 將符合出圈要求的人直接出圈(從環中刪除),剩下的人繼續報數。 這裡列的是第二種方法,刪除的方法是把該元素放到數組中的最後一個位置上,在出圈元素的後邊的 元素,都向前移動一位 實現如下: */ [cpp] 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數組中的最後一位,視為出圈,同時人數減少一個 www.2cto.com tem=p[i]; for(j=i;j<people-1;j++) { p[j]=p[j+1]; } p[j]=tem; people--; count++;//根據題意,count重新開始數數的位置是當前位置 } i++; count++; } }