1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > c语言实现约瑟夫双向生死游戏(附有详细代码)

c语言实现约瑟夫双向生死游戏(附有详细代码)

时间:2022-04-13 21:49:32

相关推荐

c语言实现约瑟夫双向生死游戏(附有详细代码)

Reborn Terran Emperor

项目简介

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

数学建模

本游戏的数学建模如下:假设n个旅客排成一个环形,依次顺序编号1,2,…,n。从某个指定的第1号开始,沿环计数,数到第m个人就让其出列,然后从第m+1个人反向计数到m-k+1个人,让其出列,然后从m-k个人开始重新正向沿环计数,再数m个人后让其出列,然后再反向数k 个人后让其出列。这个过程一直进行到剩下q个旅客为止。 本游戏的要求用户输入的内容包括:

旅客的个数,也就是n的值;正向离开旅客的间隔数,也就是m的值;反向离开旅客的间隔数,也就是k的值;所有旅客的序号作为一组数据要求存放在某种数据结构中。 本游戏要求输出的内容是包括离开旅客的序号;剩余旅客的序号;

#include <stdlib.h>#include <stdio.h> /*思路:1.建立循环链表2.创建两个链表,一个用来存放死者(数组也行)(链表太麻烦了,先用数组吧,数组不好传递,主要是忘了,还的是链表),一个用来存放总人数以及剩下的人3.需要的函数或者方法:建立新节点并赋值,尾插法,删除结点,输出两个链表,算了别搞函数了,传递太烦了,嗯,有时间再写封装函数的 *///建立结构体 struct node{int num;//存放序号struct node *next,*front; }; int main(){int n,m,k,q;//依次对应总人数,往后数隔几个死一个,往前数隔几个死,剩下几个scanf("%d %d %d %d",&n,&m,&k,&q);//创建链表 struct node *head, *tail,*newnode;//头结点和尾结点 head = (struct node *)malloc(sizeof(struct node));head->next =head->front= NULL;//创建头结点 tail=head;for(int i=1;i<=n;i++)//尾插法建立循环表 {newnode = (struct node *)malloc(sizeof(struct node));newnode->num=i;tail->next=newnode;newnode->front=tail;newnode->next=head->next;//尾结点的最后一个指向头结点的下一个,就是第一个存放数据的结点 head->next->front=newnode;//第一个存放数据的结点的前一个变成尾结点 tail=newnode;}//删除结点 struct node *right,*left;//p rl qint i=1,j=0,sign=1;int a[100];//存放死者 right = head->next;//后结点方向的名字搞错了,就当正常变量名看吧 left = tail;//前结点while(n!=q){//sign=1,往后,sign=0,往前 if(sign==1)//正向删 {if(i!=m){left = right;right = right->next;i++;}else if(i==m){left->next = right->next;right->next->front=left;a[j]=right->num;j++;free(right);right = left->next;i = 1;sign=0;n--;}}else if(sign==0)//反向删 {if(i!=k){right = left;left = left->front;i++;}else if(i==k){left->next = right->next;right->next->front=left;a[j]=right->num;j++;free(right);right=left;left = left->front;i = 1;sign=1;n--;}}}//输出链表和数组printf("死者顺序:");for(int w=0;w<j;w++){printf("%d ",a[w]); }printf("\n");printf("生者:");//遍历循环表,这里知道了循环表还剩下多少个元素,可以取巧遍历 while(right->num>right->next->num)//这一步是让p移动到循环表的开头,因为删除结点时极大可能会把头结点指向的第一个结点干了,那头结点指向的结点就会变成野指针 {right=right->next;}while(right->num>right->front->num)//双向链表由于可以判断前后才可以用这个方法 {right=right->front;}struct node *list;list=right;for(int w=0;w<q;w++){printf("%d ",list->num);list=list->next;} }

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。