环形链表解决约瑟夫游戏问题

/*
  Name:环形链表解决约瑟夫游戏问题
  Description: 假设N个旅客排成一个环形,依次顺序编号1,2,3.....,N.从某个指定的第S号开始,沿环计数,
  每数到第M个人就让他出列,且从下一个人开始重新数,继续进行下去,这个过程一直进行到剩下K个旅客为止. 
*/

//===============================约瑟夫游戏问题================================================

#include<iostream>
using namespace std;

//===============================单循环列表的结点类============================================

class Node
{
      friend class Linklist;
      public:
             Node();
             int data;
             Node *next;
};

//===============================单循环链表类==================================================

class Linklist
{
      public:
             Linklist();
             void Creatlist(Linklist &L);
             int getLength(Linklist &L);
             
             Node *Head;
};

//===============================Node类的构造函数,初始化结点数据================================

Node::Node()
{
            data = 0;
            next = NULL;
}

//===============================Linklist类的构造函数,初始化首结点数据===========================

Linklist::Linklist()
{
                    Head = NULL;
}
//===============================建立单循环链表===================================================

void Linklist::Creatlist(Linklist &L)
{
     cout << "请输入生死游戏的总人数N:";
     int n;
     cin >> n;
     Node *p;
     for(int i = n;i > 0;i--)
     {
             p = new Node;
             p->data = i;
             p->next = L.Head;
             L.Head = p;
     }
     while(p->next)
     {
                   p = p->next;
     }
     p->next = L.Head;
}  
//=================================获取单循环链表的长度=============================================

int Linklist::getLength(Linklist &L)
{
    Node *p = L.Head;
    int count = 0;
    while(p->next != L.Head)
    {
                  count++;
                  p = p->next;
    }
    count ++;
    return count;
}

//==================================主函数,实现约瑟夫生死游戏========================================

int main()
{
     cout << "现在有N个人围城一圈,从第S个人开始依次报数,报M的人出局,";
     cout << "再由下一个人开始报数,如此循环,直至剩下K个人为止" << '\n' << '\n';
     
     Linklist L;
     L.Creatlist(L);
     
     cout << "请输入游戏开始的位置S:" << '\t';
     int s;
     cin >> s;
     
     cout << "请输入死亡数字M:" << '\t';
     int m;
     cin >> m;
     
     cout << "请输入剩余的生者人数K:" << '\t';
     int k;
     cin >> k;
     
     cout << endl;
     
     Node *p,*q,*r;
     p = L.Head;
     // 找出s结点
     for(int i = 0; i < s-1;i++)
     {
             p = p->next;
     }
     
     int t = 1;
     
     while(k < L.getLength(L))
     {
             //报数,找出m结点 
             for(int j = 0;j < m-1;j++)
             {
                     q = p;
                     p = p->next;
             } 
             
             //元素出列
             if(p == L.Head) 
             {
                  r = p;
                  L.Head = p->next;
                  q->next = p->next; 
                  p = p->next;
             }
             else
             {
                 r = p;
                 q->next = p->next;
                 p = p->next;
             }
             
             cout << "第" << t <<"个死者的位置是" << '\t' << r->data << endl;
             t++;
     }
     cout << '\n' << "最后剩下:" << '\t' << L.getLength(L) << "人" <<endl;
     cout << "剩余的生者的位置为:" << '\n';
     p = L.Head;
      
     while(p->next != L.Head)
     {
                   cout << p->data << '\t';
                   p = p->next;
     }
     if(p)
     cout << p->data <<'\t';
     cout << '\n';
     
     system("pause");
     return 0;
}


转载于:https://my.oschina.net/clear/blog/53973

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值