今天讲的一道习题是很经典的约瑟夫环问题,其实lz对于链表的某些操作还不是太懂,所以在程序中有些地方还不太看得懂,这里借鉴的网上的做法,还请大牛能够解答我的疑惑,谢谢!
标题:约瑟夫环
说明:约瑟夫环是这么一个问题:已知n个人(编号1,2,。。。n)围坐在圆桌周围。从编号为k的人开始报数,数到m的人出列,他的下一个人又从1开始报数,数到m的人出列,直到所有人都出列。
struct node{
int num;
node *next;
};
node *creat(int n)//构建一个链表,即head-》1-》2-》。。。-》n,最后n又回到head
{
node *p,*q,*head=NULL;
for(int i=0;i<=n;i++)
{
p=new node;
p->num=i;
if(head==NULL)
{
head=p; //head用0来表示
}
else
{
q->next=p;
}
q=p;
}
p->next=head; //p变为最后一个节点
return p;
}
int main()
{
int n,k,m;//n为总人数,k为开始报数的人的序号,m为报到的需要出列的数
cin>>n>>k>>m;
node *l,*q;
l=creat(n);//l即为生成的链表
q=l;l=l->next;
for(int i=1;i<k;i++)//这步其实不太理解是什么意思
{
q=l;
l=l->next;
}
while(l->next!=l)//l->next==l表示只剩下最后一个人了
{
for(int i=1;i<m;i++)//如果还没有报到则依次遍历
{
q=l;
l=l->next;
}
cout<<l->num<<"->";//输出出列的人的序号
q->next=l->next;//将这个人的位置删去
delete l;
l=q->next;//用出列的下一个人来代替出列的人
}
cout<<l->num;
delete l;
}