约瑟夫环问题(武汉理工2018计算机复试题之一)

复试题仅仅把约瑟夫环问题中的固定报数改成出列人的序号,这里就按照约瑟夫环问题解决。

问题描述:有n个人围坐在一起,编号为1~n,现在从第k个人开始报数,报到m时。该人出列,并且从下一个人开始重新报数。报到m继续出列…这样下去 最后一个出列的人序号时多少?

算法思想:这样的问题,用单循环链表再合适不过了。结束条件就是p->next = p,此时p就是最后一个出列的结点。 这道题应该算是纯数据结构里的问题。

代码如下:

#include <iostream>

using namespcae std;

typedef struct Node
{
 int ID;  //编号
 struct Node *next;   //
}Node,*PNode;

PNode CreateJoseffList(int n)  //创建约瑟夫环,返回编号为1的节点地址
{
 PNode tmp = new Node;
 tmp->ID = 1;
 tmp->next = NULL;
 PNode first = tmp;
 for (int i = 2;i <= n;i++)
 {
  PNode pnode = new Node;
  pnode->ID = i;
  tmp->next = pnode;
  tmp = pnode;
 }
 tmp->next = first; //最后一个节点指向第一个节点,围成圈
 return first;
}

int BeginCount(PNode p, int k, int m)  //第k个人开始,每报到m出列
{
 PNode tmp = p;
 for (int i = 1;i < k;i++)
 {
  tmp = tmp->next;
 }
 while (tmp->next!=tmp) //如果tmp->next = tmp 说明tmp就是最后一个元素了
 {
  for (int j = 1;j < m - 1;j++) //找到报数为m-1的点,即前驱节点
   tmp = tmp->next;
  PNode q = tmp->next;
  tmp->next = tmp->next->next;
  free(q);  //删除报数为m的节点
  tmp = tmp->next;
 }
 return tmp->ID;
}

int main()
{
 int n, k, m; //第k个人开始,报到m出列
 cin >> n >> k >> m;
 PNode first = CreateJoseffList(n);
 int result = BeginCount(first, k, m);
 cout << result;
    
}
//代码并不难想,属于送分题,但是考试时时间不多,只有熟能生巧才能游刃有余。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值