数据结构编程回顾二约瑟夫生者死者游戏
目录
数据结构编程回顾(二)约瑟夫生者死者游戏
题目二:约瑟夫生者死者游戏
约瑟夫游戏的大意: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;
}