数据结构设计——约瑟夫双向生死游戏

约瑟夫双向生死游戏

[问题描述]:

约瑟夫双向生死游戏是在约瑟夫生者死者游戏的基础上,正向计数后反向计数,然后再正向计数。

具体描述如下:30个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分;因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人开始,顺时针依次报数,数到第9人,便把他投入大海中,然后从他的下一个人数起,逆时针数到第5人,将他投入大海,然后从他逆时针的下一个人数起,顺时针数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置。

[设计思路]:

本游戏的数学建模如下:假设n个旅客排成一个环形,依次顺序编号12,…,n。从某个指定的第1号开始,沿环计数,数到第m个人就让其出列,然后从第m+1个人反向计数到m-k+1个人,让其出列,然后从m-k个人开始重新正向沿环计数,再数m个人后让其出列,然后再反向数k 个人后让其出列。这个过程一直进行到剩下q个旅客为止。 也就是一个双向循环链表,分别进行正向移动和反向移动,出列相应位置的人

实现:

(1) 输入旅客的个数,也就是n的值;

(2)正向离开旅客的间隔数,也就是m的值;

(3) 反向离开旅客的间隔数,也就是k的值;

(4) 输出出列的人所在的位置

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct LinkList{
    int data;
    struct LinkList *pri;
    struct LinkList *next;
}LinkList;

//尾插入法建立链表   链表的头结点head作为返回值
LinkList  *create_LinkListWEI(int n)
{
    LinkList *head, *p, *q;
    head = p =(LinkList*)malloc(sizeof(LinkList));
    p->pri = NULL;
    int i = 2;// 位置
    p->data = 1;
    n--;
    while(n--){
        q = (LinkList  *)malloc(sizeof(LinkList));
        q->data = i;
        q->next = NULL;
        p->next = q;
        q->pri = p;
        p = q;
        i++;
    }
    q->next = head;
    head->pri = q;
    return head;
}

void print(LinkList *head,int n){
    printf("
正向:
");
    LinkList *p = head;
    int num = 0;
    while(p->next){
        printf("%d ",p->data);
        p = p->next;
        num++;
        if(num >= n)
            break;
    }
    num = 0;
    printf("
反向:
");
    p = head;
    while(p->pri){
        printf("%d ",p->pri->data);
        p = p->pri;
        num++;
        if(num >= n)
            break;
    }
    printf("
");
}

LinkList  *kill_m(LinkList *head,int m){
    LinkList *p = head;
    LinkList *q;
    int time = 1;
    while(p->next){
        q = p->next;
        if(time == m){
            printf("%d ",p->data);
            //删除链表结点 p
            p->pri->next = q;
            q->pri = p->pri;
            return q;
        }
        p = p->next;
        time++;
    }

}

LinkList  *kill_k(LinkList *head,int k){
    LinkList *p = head;
    LinkList *q;
    int time = 1;
    while(p->pri){
        q = p->pri;
        if(time == k){
            printf("%d ",p->data);
            //删除链表结点 p
            q->next = p->next;
            p->next->pri = q;
            return q;
        }
        p = p->pri;
        time++;
    }
}

int main(){
    int all,m,k;
    /*
    m 正向    k 反向
    */
    scanf("%d %d %d",&all,&m,&k);
    LinkList *p,*q;
    p = create_LinkListWEI(all);
    printf("双向链表的构建:
");
    print(p,all);
    printf("
");
    // 杀人
    int flag = 1;
    int re = all / 2;
    q = p;
    printf("
被踢下船的人所在位置:
");
    while(all > re){
        if(flag == 1)
            q = kill_m(q,m);
        else
            q = kill_k(q,k);
        //printf("
q->data:%d
",q->data);
        flag *= -1;
        all--;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/expedition/p/12207060.html