问题描述:约瑟夫环是一个数学的应用问题:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
分析:1、这个题最直接最常用的便是模拟,有数组模拟,或者循环链表模拟都可,但是后者删除时移动的次数少,但本题如果数据要求不大,两者就差不多了,复杂度都是O(mn)。
直接上代码:(不解释太多)
#include<cstdio>
#include<cstdlib>
structnode
{
int data;
struct node *next;
};
structnode* jianli(int n)
{
int i;
struct node *head,*tail,*ptr;
head=tail=NULL;
for (i=1;i<=n;i++)
{
ptr=(struct node *)malloc(sizeof(structnode));
ptr->data=i;
ptr->next=NULL;
if (head==NULL)
head=ptr;
else
tail->next=ptr;
tail=ptr;
}
tail->next=head;
return head;
}
voiddel(struct node *head)
{
struct node* ptr;
ptr=(struct node *)malloc(sizeof(structnode));
ptr=head;
struct node* ptr1;
ptr1=(struct node *)malloc(sizeof(structnode));
ptr1=ptr->next;
ptr->next=ptr1->next;
free(ptr1);
}
intmain()
{
struct node *head,*ptr;
int n,m;
head=(struct node *)malloc(sizeof(structnode));
while (scanf("%d%d",&n,&m)!=EOF)
{head=jianli(n);
ptr=head;
int t=1;
if (n==1) printf("1\n");
else if (n==2) printf("2\n");
else
{while (n>1)
{
if (t<m-1) {t++;ptr=ptr->next;}
else { struct node *ptr1;
ptr1=(struct node*)malloc(sizeof(struct node));
ptr1=ptr;
ptr=ptr->next->next;
t=1;
del(ptr1);
n--;}
}
printf("%d\n",ptr->data);}}
return 0;
}
后面的优化方法转载于http://blog.csdn.net/zhang20072844/article/details/9772441