约瑟夫问题1:
约瑟夫问题是一个非常著名的趣题,即由n个人坐成一圈,按顺时针由1开始给他们编号。然后由第一个人开始报数,数到m的人出局。现在需要求的是最后一个出局的人的编号。
1.1数组法:
用一个数组记录所有人的状态,初始值为各自的变化,如果位置的人出局,则将其值设为0。
int getResult(int n, int m) {
// write code here
vector <int> a(n+1);
int dead_num =0;
int num=0;
int i;
for(i=1;i<=n;i++)
a[i]=i;
for(i=1;;i++){
if(i>n)
i=i%n;
if(a[i]>0)
num++;
//如果出局,则将位置值设为0,出局人数加1,报数值设为初始值
if(m==num && dead_num!=n-1){
a[i]=0;
num=0;
dead_num++;
}
//如果正好为出局位置,且人数只剩下一人,则改位置即为最后一个出局的人
else if(m==num && dead_num==n-1){
return a[i];
}
}
return 0;
}
1.2 链表法
使用循环链表实现
typedef struct node{
int data;
struct node *next;
}LinkList;
int getResult(int n, int m) {
// write code here
LinkList *L,*r,*s;
L=(LinkList *)malloc(sizeof(LinkList));
r=L;
//使用尾插法建立带有头结点的循环链表
for(int i=1;i<=n;i++){
s=(LinkList *)malloc(sizeof(LinkList));
s->data=i;
r->next=s;
r=s;
}
r->next=L->next;
LinkList *p=L->next;
while(p->next!=p){
for(int i=1;i<m-1;i++){
p=p->next;
}
p->next=p->next->next;
p=p->next;
}
return p->data;
}