面试中经常会被问到报数游戏。遂实现一下。
问题描述:
设有N个人围坐一圈并按顺时针方向从1到N编号,从第S个人开始进行1到M报数,报数到第M个人时,此人出圈,再从他的下一个人重新开始1到M的报数,如此进行下去直到所有的人都出圈为止。现要打印出出圈次序。
输入:n 游戏总人数 s 报数的起始编号 m 报数的数值
输出:p 指向长度为n的数组,出圈次序保存在p指向的数组中
示例
n=7 s=2 m=3 出圈次序为:4 7 3 1 6 2 5
n=3 s=1 m=2 出圈次序为:2 1 3
用循环链表实现如下:
#include <iostream>
using namespace std;
typedef struct tagNode
{
int data;
struct tagNode *next;
}node;
void Joseph(int count, int start, int steps)
{
node *p, *q, *head;
head = (node *)new node;
p = head;
for (int i=1; i<=count-1; i++)
{
p->data = i;
p->next = (node *)new node;
p= p->next;
}
p->data = count; //最后一位队员最后特殊处理,形成循环链表
p->next = head;
p= head;
while(p->next != p)
{
while(p->data!=start)
p = p->next;
if (steps == 1)
{
for (int i=1; i<=count; i++)
{
cout<<p->data<<"\t";
p=p->next;
}
cout<<endl;
return;
}
else
{
for (i=1;i<steps-1;i++)
{
p=p->next; //p指向待出列队员的前一位
}
q=p->next;
cout<<q->data<<"\t"; //q为待出列队员
p->next = q->next; //重新连接链表
delete q;
start = p->next->data; //p所指队员的下一位为下一轮第一个报数队员
}
}
cout<<p->data; //输出最后一个出列队员
delete p;
cout<<endl;
}
int main(int argc, char* argv[])
{
int count,start,steps;
cin>>count>>start>>steps;
Joseph(count,start,steps);
return 0;
}