约瑟夫问题以及加强版

据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏

#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
    int elem;
    struct Node *Next;
}Node;
Node *head=NULL;
Node *create(int n){
    Node *temp;
    Node *target;
    head=(Node*)malloc(sizeof(Node));
    temp=head;
    int i=1;
    if(n!=0){
        while(i<=n){
            target=(Node*)malloc(sizeof(Node));
            target->elem=i++;
            temp->Next=target;
            temp=target;
        }
        temp->Next=head->Next;
    }
    free(head);
    return temp->Next;
}
void delete(int m,int n,Node *q){
    Node *p=q;
    Node *temp;
    m%=n;//获取循环次数
    int i;
    while(q!=q->Next){
        for(i=1;i<m-1;i++){//找到要删除节点的前节点
            q=q->Next;
        }
        printf("%d->",q->Next->elem);
        temp=q->Next;
        q->Next=temp->Next;
        free(temp);
        q=q->Next;
    }
    printf("%d",q->elem);
}
int main(){
    int n=41;
    int m=3;
    Node *head=create(n);
    delete(m,n,head);
}

加强版:

提高挑战难度:编号为1~N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数,可以自由输入),开始又选一个正整数作为报数上限值M,从第一个人按顺时针方向自1开始顺序报数,报道M时停止报数。报M的人出列,将他的密码作为新的M值,从他顺时针方向上的下一个人开始从1报数,如此下去,直至所有人全部出列为止。

#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
    int elem;
    struct Node *Next;
}Node;
Node *head=NULL;
int j;
Node *create(int n){
    Node *temp;
    Node *target;
    head=(Node*)malloc(sizeof(Node));
    temp=head;
    int i=1;
    if(n!=0){
        while(i<=n){
            target=(Node*)malloc(sizeof(Node));
            scanf("%d",&j);
            target->elem=j;
            temp->Next=target;
            temp=target;
            i++;
        }
        temp->Next=head->Next;
    }
    free(head);
    return temp->Next;
}
void delete(int n,int m,Node *q){
    Node *p=q;
    Node *temp;
    m%=n;
    int i;
    while(q!=q->Next){
        for(i=1;i<m-1;i++){
            q=q->Next;
        }
        m=q->Next->elem%n;
        printf("%d->",q->Next->elem);
        temp=q->Next;
        q->Next=temp->Next;
        free(temp);
        q=q->Next;
    }
    printf("%d",q->elem);
}
int main(){
    int m,n;
    scanf("%d%d",&m,&n);
    Node *head=create(n);
    delete(n,m,head);
}

 

posted @ 2021-08-02 15:54  不负韶华。  阅读(82)  评论(0编辑  收藏  举报