1. 程式人生 > >約瑟夫問題(連結串列)

約瑟夫問題(連結串列)

#include<bits/stdc++.h>
using namespace std;
struct node
{int num;//記錄這個結點對應猴子的編號
node *next,*pre;//next指向結點的後繼,pre指向結點的前驅
}*head,*tail,*p;//head表示頭指標,tail表示尾指標
int n,m;
int main()
{
    while(cin>>n>>m,n||m)//判斷n,m是否為0 0
    {
        head=new node;
        head->num=1;
        head->next->pre=NULL;
        tail=head;//先建立編號為1的結點,頭指標和尾指標此時都指向它
        for(int i=2;i<=n;i++)
        {
            p=new node;
            p->num=i;//建立編號為i的結點
          tail->next=p;
          p->pre=tail;//將p指向的結點插入到tail指向的結點的後面
          p->next=NULL;
          tail=p;//將tail更新為p,下次就插入到它的後面
        }
        head->pre=tail;
        tail->next=head;//因為是迴圈連結串列,所以頭尾項鍊
        p=head;
        for(int i=1;i<n;i++)//因為我們要輸出剩下的最後一個的編號
        {//所以只要迴圈(n-1)次,每次刪除一個結點,即可確定答案
            for(int j=1;j<m;j++)
            p=p->next;//經過(m-1)次,p指向要刪除的那個結點
            p->next->pre=p->pre;
            p->pre->next=p->next;//刪除結點p
            p=p->next;//剩下的猴子就從剛剛刪除的結點的後繼開始報數
        }
        cout<<p->num<<endl;//最後剩餘一個結點,則這個結點的編號即為答案
    }
}