猴子选大王问题
描述
一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1~m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。利用单向循环链表模拟此过程,依次输出出圈的猴子编号。
输入
多组数据,每组数据占一行,包括两个数据m和n。m代表猴子个数,n代表步数,m=0且n=0时输入结束。
输出
依次输出出圈的猴子编号,编号之间用空格隔开。
样例输入1
10 4 8 3 0 0
样例输出1
4 8 2 7 3 10 9 1 6 5 3 6 1 5 2 8 4 7
解答:建立循环链表。反复遍历循环链表直到链表中只剩下一个结点,输出所求结点的数据,同时删除该结点。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
} Node,*List;
void Create(List &L,int n)
{
Node *p,*rear;
L=(Node *)malloc(sizeof(Node));
L->data=0;
L->next=NULL;
rear=L;
for(int i=1; i<=n; i++)
{
p=(Node *)malloc(sizeof(Node));
p->data=i;
p->next=rear->next;
rear->next=p;
rear=p;
L->data++;
}
rear->next=L;
}
void Find(List &L,int n)
{
Node *p,*q;
p=L;
while(L->data > 1)
{
for(int i=1; i<n; i++)
{
p=p->next;
if(p==L)
p=p->next;
}
if(p->next==L)
{
p=L;
}
printf("%d ",p->next->data);
q=p->next;
p->next=q->next;
free(q);
L->data--;
}
printf("%d\n",L->next->data);
}
int main()
{
int m,n;
List L;
while(1)
{
scanf("%d %d",&m,&n);
if(m==0 && n==0)
break;
Create(L,m);
Find(L,n);
}
return 0;
}