约瑟夫问题是一个有趣的游戏。有n个人围成一圈,从第一个人开始沿顺时针方向报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那个人?
比如输入5,输出4
思路:循环链表,模拟运行,见代码注释
#include <iostream>
#include <algorithm>
using namespace std;
//创建链表结构体
typedef struct node
{
int date;
struct node *next;
}node;
//创建结点
node *create(node *L,int n)
{
L=(node *)malloc(sizeof(node));
node *p,*s;
s=L;
for(int i=1;i<=n;i++)//尾插法
{
p=(node *)malloc(sizeof(node));
p->date=i;
p->next=NULL;
s->next=p;
s=s->next;
}
s->next=L->next;//最后元素的next指向第一个元素 构成循环
free(L);//删除头结点
return s->next;
}
int main()
{
int n,count=1;//修改count可以设置约瑟夫环的大小
cin>>n;
node *L=create(L,n);
node *p=L;
node *r;
while(p->next!=p)
{
for(int i=0;i<count;i++)
{
p=p->next;
}//当链表走到删除元素之前的时候停止,方便找到删除元素地址
r=p->next;//删除操作
p->next=r->next;
cout<<r->date<<"->";//依次输出删除元素
free(r);
p=p->next;//在删除元素的下一位置重新计数
}
cout<<p->date<<endl;//最后一人
return 0;
}