约瑟夫环是数据结构中一道经典且基础的问题,它本身可以通过循环链表实现,也可以通过递推公式来进行递归。本题提供两种写法,一是循环链表,二是公式递归法。
1.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct LNode
{
int date;
struct LNode *next;
}LNode,*Linklist;
Linklist creat(int n)
{
int i=1;
Linklist end,head,p;
head=(Linklist)malloc(sizeof(LNode));
head->next=NULL;
end=head;
while(n--)
{
p=(Linklist)malloc(sizeof(LNode));
p->date=i++;
end->next=p;
end=p;
}
end->next=head->next;
free(head);
return end->next;
}
int main()
{
int n,m,i;
scanf("%d%d",&n,&m);
Linklist t,p=creat(n);
while(p->next!=p)
{
for(i=1;i<m-1;i++)
{
p=p->next;
}
t=p->next;
p->next=t->next;
free(t);
p=p->next;
}
printf("%d",p->date);
}
2.公式递归法
#include<stdio.h>
int cir(int n,int m)
{
if(n==1)
{
return 0;
}
else
{
return (cir(n-1,m)+m)%n;
}
}
int main()
{
int m,n;
scanf("%d %d",&n,&m);
printf("%d",cir(n,m)+1);
return 0;
}
注:约瑟夫环可通过f(n)=(f(n-1)+m)%n求得,f(n)表示有n个人时的结果。