最近忙著提升自身的訪談能力,美其曰:“提高自身的業務能力”,兩字呵呵。感覺在公司前途一片黑暗,連絲曙光都不見,好在我有一顆強大的❤,感謝mother 。因為模擬對象中有一位學習中等,在班中揚言..... 此處略去一百字,所以我就想到自己教過的學生中就有這麼一位。 然後就和他QQ聊了兩句,我怎麼能這麼敬業呢O__O"…。 沒想到該學生現在准備學IOS,IOS可是我一直想去學沒學的技術啊,簡直帥爆了。 今天早上他給我發了一道題:約瑟夫環的數組實現。為了打發我郁悶苦逼的心情和大把的時間,做了一下。 最後發現網上有寫好的demo比我的要好,於是乎我就重新整理,添加了注釋。題和正解如下:
約瑟夫環的數組實現
約瑟夫(Josephus)問題是由古羅馬的史學家約瑟夫提出的,他參加並記錄了公元 66-70 年猶太人反抗羅馬的起義。約瑟夫作為一個將軍,設法守住了裘達 伯特城達 47 天之久,在城市淪陷之後,他和 40 名將士在附近的一個洞穴中避難。在哪裡,將士們群情激奮並表示:要投降毋寧死。於是,約瑟夫建議每個人輪流殺死他旁邊的人,而這個順序是由抽簽決定的。約瑟夫有預謀地抓到了
最後一簽並且做為洞穴中兩個幸存者之一生存下來。
約瑟夫環問題的具體描述是:設有編號為 1,2,......,n 的 n(n>0)個人圍成一 個圈,從第一個人開始報數,報到 m 時停止報數,報 m 的人出圈,再從他的 下一個人起重新報數,
報到 m 時停止報數,報 m 的出圈,......,如此下去,知道只剩下一人為止。當任意給定 n 和 m 後,設計算法求 n 個人出圈的次序。
假設有n=5 ,5個人: 1 ,2 , 3, 4, 5 ,
從第1個人開始報數字, 如果報的數字m為 2, 這個人被同伴殺死,出局
被殺死人的順序是: 2, 4, 3, 1, 5
代碼如下
其實用數組很難的
建議你用循環鏈表,不過我用數組寫一個給你不知道你會不會看得懂
void shuzu(int n,int m,int s)
{//n為元素個數,m為要刪除的號數,s是當前要刪除的
//同時s也是報數的開始
int a[],j,i;
for(i=1;i<n+1;i++)
a[i]=i;//排列
printf("\n");
for(i=n;i>=2;i--)//i為當前的表(數組中非0元)長
{s=(s+m-1)%i;//是要刪除,同時也控制轉向
if(s==0)s=i;//當s=i時不轉向所以s還不為0而是i
printf("%d",a[s]);
for(j=s;j<=i-1;j++)
a[j]=a[j+1];//從s開始都前移一位,這樣刪除s
}
printf("\n");
printf("%d",a[i]);
}
#include<stdio.h>
#define max 100
int main()
{
int JOSEPHU[max];
int N,M,begin; /* N: total number M: skip begin: begin */
int flag=0; /* If flag is equal to M, print the current number. */
int i; /* Contrl tht loop */
printf("Input N,M and begin: ");
scanf("%d %d %d",&N,&M,&begin);
printf("\n");
begin=begin-1;
/* Assignment the array and assignment the element not used 0 and finally display it. */
for(i=0;i<N;i++)
{
JOSEPHU[i]=i+1;
printf("%d ",JOSEPHU[i]);
}
for(i=N;i<max;i++)
JOSEPHU[i]=0;
printf("\n\n");
/* JOSEPHU[begin]=JOSEPHU[begin-1] */
for(i=2;;i++)
{
if(JOSEPHU[begin]!=JOSEPHU[N-1]) /* If the current element is not equal to the last elemnet of array JOSEPHU,then the next element. */
begin++;
else
{
begin=0; /* If the current element is equal to the last element,then the first element. */
while(JOSEPHU[begin]<0) /* When there are negative elements,skip them. */
begin++;
if(i%M==0) /* If satisfied, print the element and assignment it as negative, and increase the value of flag. */
{
printf("%d ",JOSEPHU[begin]);
JOSEPHU[begin]=-JOSEPHU[begin];
flag++;
}
if(flag==N) /* If flag is equal to total number, the loop is broken. */
break;
......余下全文>>