约瑟夫问题初探

来源:互联网 发布:意式 咖啡机推荐 知乎 编辑:程序博客网 时间:2024/06/06 17:20

约瑟夫问题:

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

 

利用循环链表求解:

#include<stdio.h>struct node{    int num;    struct node *next;};void joesphus(int n, int k, int m){    //构造循环链表    struct node *head,*p1,*p2;    int i;    p1 = p2 = (struct node*)malloc(sizeof(struct node));    head = p1;    head->num = 1;    for(i = 1; i < n; i++)    {        p1 = (struct node*)malloc(sizeof(struct node));        if(p1 == NULL)        {            return;        }        p1->num = i + 1;        p2->next = p1;        p2 = p1;    }    p2->next = head;        //移到指定的开始位置K    for(i = 1; i < k; i++)    {        head = head->next;    }    //求解,其中q指向p的前一位置,方便报数m的节点的删除操作    struct node *p =head;    int cnt = 1;    while(p != p->next)    {        struct node *q = p;        p = p->next;        cnt++;        if(cnt == m)        {            struct node *temp = p;            q->next = p->next;            p = p->next;            printf("%d\n",temp->num);            free(temp);            cnt = 1;        }    }    printf("the last:%d\n",p->num);    free(p);    }int main(){       int n,k,m;    printf("pleast input the n, k and m:\n");    scanf("%d,%d,%d",&n,&k,&m);    joesphus(n, k, m);    return 0;}


 

数学方法求解:(待续)

原创粉丝点击