由题可知,n个人围成一圈可以画出图来看
当踢掉一个人的时候,我们就可以将他指向的下一个,给到他前面的人,这样就可以踢掉这个人,就像要将7踢掉,则将6下一个指向8,来将7给跳过,
如图
所以这里我们就可以建立循环链表来实现这个功能。
首先我们先构造结构体指针
#include<stdio.h>
#include<stdlib.h>
int n,k;
typedef struct Clink
{
int data;
Clink* next;
}linkcode,*linklist;
然后在初始化循环链表
int initlink(linklist &l)//初始化循环链表
{
l=(linklist)malloc(sizeof(linkcode));
if(!l)
{
return 0;
exit(0);
}
l->next=l;//头尾相连
return 1;
}
在根据n,来判断循环链表的长度,再用尾插法进行赋值
void creattatil(linklist &l)//尾插法给链表赋值
{
l->data=1;
linklist p=l;
for(int i=2;i<=n;i++)
{
linklist q;
q=(linklist)malloc(sizeof(linkcode));
q->data=i;
p->next=q;
p=q;
}
p->next=l;//最后将尾结点的next指向头节点,来实现头尾相连,形成循环链表。
}
链表构建完毕后,就开始模拟踢人操作
void turnout(linklist &l)
{
int x=1;//x用来表示第几个人
linklist p=l;
linklist q=l;
while(q->next->next!=l)//将q移动到链表的尾部 ,让q为p的前一项
{
q=q->next;
}
while(p->next!=p)//如果p->next==p的话,就代表链表中只剩一个元素。
{
if(x%k!=0)//看是数到第几个人,当x是k的倍数时,则当前的人就要被踢掉
{
q=p;
p=p->next;
}
else
{
printf("%d ",p->data);
q->next=p->next;//把q的下一个指向p的下一个,来删除p;
free(p);
p=q->next;
}
x++;
}
printf("%d",p->data);
}
int main()
{
linklist l;
scanf("%d%d",&n,&k);//n为多少个人,k为数到k时退出
if(initlink(l))
{
creattatil(l);//尾插法
turnout(l);//踢人
}
}