设计题目:约瑟夫生死游戏〔问题描述〕:约瑟夫生死游戏的大意是:30个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分;因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人开始,依次报数,数到第9人,便把他投入大海中,然后从他的下一个人数起,数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置。〔基本要求〕本游戏的数学建模如下:假设n个旅客排成一个环形,依次顺序编号1,2,…,n。从某个指定的第1号开始,沿环计数,每数到第m个人就让其出列,且从下一个人开始重新计数,继续进行下去。这个过程一直进行到剩下k个旅客为止。
一样的问题:
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode {
int date;
struct Lnode *next;
}LNode;
LNode *create_LinkList(int a) {
LNode *head, *rear, *p;
head = rear = (LNode *)malloc(sizeof(LNode));
head->next = head;
head->date = 1;
for (int i = 2; i <= a; i++) {
if (i == 32767) break;
p = (LNode *)malloc(sizeof(LNode));
p->date = i;
p->next = rear->next;
rear->next = p;
rear = p;
}
return head;
}
LNode im(int a, int b, int c)
{//a,原始人数;b,删除序号,c,幸存人数
LNode *p = create_LinkList(a);
for (int i = 1; i < a; i++)
{
p = p->next;
}
for (int i = 1; i <= a - c; i++)
{//大循环,删除的个数
LNode *q = p->next;
if (b > 1)
{
for (int j = 1; j <= b - 1; j++)
{//小循环,让P指针移动几次
p = q;
q = q->next;
}
printf("%d ", q->date);
p->next = q->next;
free(q);
}
else
{
printf("%d ", q->date);
p->next = q->next;
free(q);
}
}
printf("\n幸存者序号依次为:\n");
for (int i = 1; i <= c; i++) {
printf("%d ", p->date);
p = p->next;
}
return *p;
}
int main(){
int a, b, c;
printf("请输入初始总人数和要被扔下去的序号:");
scanf_s("%d %d", &a, &b);
printf("请输入幸存人数:");
scanf_s("%d", &c);
*create_LinkList(a);
printf("初始的编号是:\n");
for (int i = 1; i <= a; i++) { printf("%d ", i); }
printf("\n");
printf("被扔下去的人依次为:\n");
im(a, b, c);
}