复试题仅仅把约瑟夫环问题中的固定报数改成出列人的序号,这里就按照约瑟夫环问题解决。
问题描述:有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;
}
//代码并不难想,属于送分题,但是考试时时间不多,只有熟能生巧才能游刃有余。