目录

数据结构编程回顾二约瑟夫生者死者游戏

目录

数据结构编程回顾(二)约瑟夫生者死者游戏

题目二:约瑟夫生者死者游戏

约瑟夫游戏的大意:30 个游客同乘一条船,因为严重超载,

加上风浪大作,危险万分。因此船长告诉乘客,只有将全船

一半的旅客投入海中,其余人才能幸免于难。无奈,大家只

得同意这种办法,并议定30 个人围成一圈,由第一个人数

起,依次报数,数到第9 人,便把他投入大海中,然后再从

他的下一个人数起,数到第9 人,再将他投入大海中,如此

循环地进行,直到剩下15 个游客为止。问:哪些位置是将

被扔下大海的位置?

不失一般性,将30 改为一个任意输入的正整数n,而报数

上限(原为9)也为一个任选的正整数k。

这道理应该是想要用顺序表来,由于我比较懒,直接用数组实现了(毕竟数组是扩展嘛 都一样 道理懂就行)

假设一共有m个人,每第k个就会被投入大海,最后剩下n个人时停止:

1.建立一个长度为m的数组people,初始化为0

2.设置变量count 每当遍历一个活人(people[i]==0),则+1

3.当count%k==0时,即每当数到k时,这个人被投入大海,即置people[i]=1

4.如果访问游标i小于总人数,则+1,否则移动到开始,即1,完成循环的功能

代码如下:

//约瑟夫生死游戏
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main() {
	
	int m;//一共人数
	int k;//计数上限
	int n;//最后存活人数
	int people[99];//总人数
	memset(people,0,sizeof(people));//为0   则保留  1  则扔掉
	int count=0;//总计数器
	int c=0;//目前被扔的人数
	int i=1;
	printf("请输入总人数:\n");
	scanf("%d",&m);
	printf("请输入报数上限:\n");
	scanf("%d",&k);
	printf("请输入最后幸免人数:\n");
	scanf("%d",&n);
	while(1) {
		if(c==m-n)
			break;
		if(people[i]==0) {
			count++;
			if(count%k==0) { //被扔的人
				people[i]=1;
				c++;
			}
		}
		if(i<m)
			i++;
		else
			i=1;
	}
	printf("以下位置不被扔下大海:");
	for(i=1; i<=m; i++)
		if(people[i]==0) {
			printf("%d",i);
			if(i!=m)
				printf(" ");
		}
	return 0;
}