寒假專案2-猴子選大王

不被看好的青春叫成長發表於2015-01-30

/* 

* Copyright (c) 2014, 煙臺大學計算機學院 
* All rights reserved. 
* 檔名稱:test.cpp 
* 作    者:劉暢 
* 完成日期:2015 年 1  月  30  日 
* 版 本 號:v1.0 
* 
* 問題描述:一群猴子,編號是1,2,3 ...m,這群猴子(m個)按照1-m的順序圍坐一圈。從第1只開始數,每數到第n個,該猴子就要離開此圈,這樣依次下來,直到圈中只剩下最後一隻猴子,則該猴子為大王。輸入m和n,輸出為大王的猴子是幾號。  
* 輸入描述:輸入猴子的個數m和被提出的數n
* 程式輸出:輸出為大王的猴子號碼。

提示1:(1)連結串列解法:可以用一個迴圈的單連結串列來表示這一群猴子。表示結點的結構體中有兩個成員:一個儲存猴子的編號,一個為指向下一個人的指標,編號為m的結點再指向編號為1的結點,以此構成環形的鏈。當數到第n個時,該結點被刪除,繼續數,直到只有一個結點。(2)使用結構陣列來表示迴圈鏈:結構體中設一個成員表示對應的猴子是否已經被淘汰。從第一個人未被淘汰的數起,每數到n時,將結構中的標記改為0,表示這隻猴子已被淘汰。當數到陣列中第m個元素後,重新從第一個數起,這樣迴圈計數直到有m-1被淘汰。
提示2:該題為電腦科學中的經典問題,很多實際的問題可以抽象到這種模型上來。感興趣的同學請搜尋“約瑟夫問題”

程式碼如下:

#include <iostream>
using namespace std;
struct Node
{
    int num;                         //猴子的編號
    Node *next;                       //下一隻猴子
};

int main()
{
    int m,n,i,j,king;
    Node *head, *p,*q;
    cin>>m>>n;
    if(n==1)
    {
        king=m;
    }
    else                                 //建立猴子圍成的圓圈
    {
        p=q=new Node;
        head = p;
        head->num=1;
        for(i=1,p->num=1; i<m; i++)      //其餘m-1只猴子
        {
            p=new Node;                  //p是新增加的
            p->num=i+1;
            q->next=p;
            q=p;                         //q總是上一隻
        }
        q->next=head;                     //最後一隻再指向第一隻,成了一個圓圈

        //下面開始數了
        p=head;
        for(i=1; i<m; i++)                //迴圈m-1次,淘汰m-1只猴子
        {
        //從p1開始,數n-1只就找到第n只了
            for(j=1; j<n-1; j++)         //實際先找到第n-1只,下一隻將是被淘汰的
                p=p->next;               //圍成圈的,可能再開始從第一隻數,如果還未被淘汰的話

            //找到了,
            q=p->next;                   //q將被刪除
            p->next=q->next;             //q就這樣被“架空了”
            p=q->next;                   //下一輪數數的新起點
            delete q;                    //將不在連結串列中的結點刪除
        }
        king=p->num;
        delete p;
    }
    cout<<king<<endl;
    return 0;
}


執行結果:

示例推理:


連結串列真心沒大弄明白,對照老師的一步一步來做也還是有很多地方沒弄明白,靠自己再寫肯定還是寫不出來的T.T。努力吧!

相關文章