约瑟夫问题(Josephus)

(easy版本)已知 n 个人(以编号1, 2, 3 ,4, 5 ,6  ... .. .n)围坐一张圆桌周围。从编号为s 的人开始报数,数到m 的那个人出列;他的下一个人又从 1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。

#include <iostream>
using namespace std;

struct node
{
    int data;
    node *next;
};

main()
{
    /*假设共有n人,从第s个人开始数数,每数到m该人出列,后面的人重新开始数,知道全部人出列*/
    int n,s,m;
    node *current,*prev;
    node *head=new node;
    head->data=1;                            //这里的头指针等同于第一个节点
    prev=head;
    cout << "Input the n,s,m(separate with space):";
    cin >> n >> s >> m;

    for(int i=2;i<=n;i++)      //建立循环链表
    {
        current = new node;
        current->data = i;
        prev->next=current;
        prev=current;
    }
    current->next=head;
    
    current = head; //遍历循环链表,输出序列
    do
    {
        cout << current->data<< " ";
        current = current->next;
    }  while(current!=head);

    current = head; //将current置于第s个位置
    for(int i=1;i<s;i++)
    {
        current = current->next;
    }
    cout << endl;

    for(int i=1;i<=n;i++) //共循环n轮,得到一个整体的输出序列
    {
        for(int j=1;j<m;j++)
        {
            prev=current;           //在current前一个位置 
            current = current->next;
        }
        cout << current->data << " ";
        prev->next = current->next;
        delete current;
        current = prev->next;
    }
}

 

(hard版本)题目:约瑟夫双向生死游戏是在约瑟夫生者死者游戏的基础上,正向计数后反向计数,然后再正向计数。具体描述如下:30(NumofPeople)个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分;因此船长告诉乘客,只有将全船一半(NumofKilled)的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人开始,顺时针依次报数,数到第9(ForwardCount)人,便把他投入大海中,然后从他的顺时针的下一个人数起,逆时针数到第5(ReverseCount)人,将他投入大海,然后从他逆时针的下一个人数起,顺时针数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置。

 

#include <iostream>
using namespace std;

struct node
{
    int data;
    node *prior,*next;
};

main()
{
    /*假设共有n人,从第s个人开始数数,后面的人重新开始数,直到15人出列*/
    int n,s;
    cout << "Input the n,s(separate with space):";
    cin >> n >> s ;
    node *current,*prev;
    node *head=new node;    //这次head指向一个圈, head在圈外 ,head->next是第一个节点 
    head->next=head;
    head->prior=head;
    prev=head;
    
    for(int i=1;i<=n;i++)      //建立双循环链表
    {
        current = new node;
        current->data = i;
        prev->next=current;
        current->prior=prev;      
        prev=current;       
    }
    current->next=head->next;
    head->next->prior=current;
    
    current = head->next; //遍历循环链表,输出序列
    for(int i=1;i<=n;i++) 
    {
        cout << current->data<< " ";
        current = current->next;
    }  

    current = head->next; //将current置于第s个位置
    for(int i=1;i<s;i++)
    {
        current = current->next;
    }
    cout << endl;

    for(int i=1;i<=15;i++) //共循环15轮,得到一个输出序列
    {
        if(i%2==1)       // 正向
        {
            for(int j=1;j<9;j++)
            {
                prev=current;            //指向前一个位置 
                current=current->next;
            }
            cout<<current->data<<" ";
            prev->next=current->next;
            current->next->prior=prev;
            delete current;
            current=prev->next;
        }
        else           //逆向 
        {
            for(int j=1;j<5;j++)
            {
                prev=current;             //指向后一个位置 
                current=current->prior;
            }
            cout<<current->data<<" ";
            prev->prior=current->prior;
            current->prior->next=prev;
            delete current;
            current=prev->prior;
        }
    }
    return 0;
}

截图:

猜你喜欢

转载自blog.csdn.net/Drifter_Galaxy/article/details/81609087
今日推荐