一_题目
有n个人围成一个圈,开始报数,报到m的人出局,并且不再参加报数,依次类推,直到n个人全部出局为止。
二_分析
1.将抽象的问题实例化
假设有一个裁判:
mouth:取值范围 1~m (报到m的人出局)
finger: 取值范围1~n (总共有n个人)
2.对n,m赋值,个人模拟报数
假设
n==8, m==5
那么出局的人的依次是: 5 2 87 1463
3.从个人模拟报数中发现问题
代码如下:(具体解释在代码注释中)
int n=0;//参加报数的总人数 int m=0;//报到m的人出局scanf("%d",&n);scanf("%d",&m); //输入完毕 int table[1005]={0};//数据规模可以开大一些 for(int i=1;i<=n;i++)//将数组中的人先全部标号为 1 ,之后出局的人标号为 0 {table[i]=1; } //开始操作 int mouth=0;//1~m//mouth==m怎么办?int finger=0;//1~n //table[finger]==0怎么办?
易发现,问题的关键在于:
Ⅰ.mouth==m怎么办?
Ⅱ.table[finger]==0怎么办?
将以上两个问题思考清楚了,这个问题也就解决了。
4.解决问题
在代码中具体操作(多说无益,在问题中解决问题):
int cnt=n; //cnt需要实现--的操作,以结束代码while(cnt!=0)//表示还有人在参加报数 { mouth++; finger++; while(table[finger]==0)//如果指到空位了的操作{ finger++;//不管这个空位,finger继续++if(finger>n)//finger超过了总人数{ finger=1;//重新将finger赋值为1} } if(mouth==m)//有人报到m这个数了,需要出局{ printf("%d ",finger);//打印出局的人的编号 table[finger]=0;//将出局的人标号为0,表示不再参加报数cnt--;//参加报数的人 -- mouth = 0;//更新 mouth 的值} }
三_总结
可以解决约瑟夫环问题的方法有很多种:
如,递归,链表等等。
本文仅仅介绍最为简单的一种(数组),学会本文万不可妄自菲薄,知识海洋深不见底,无人可窥之全貌。
下面将全部代码附上,请君观之,如有不足敬请指点!
#includeint main(){int n=0;//参加报数的总人数 int m=0;//报到m的人出局scanf("%d",&n);scanf("%d",&m); //输入完毕 int table[1005]={0};//数据规模可以开大一些 for(int i=1;in)//finger超过了总人数{ finger=1;//重新将finger赋值为1} } if(mouth==m)//有人报到m这个数了,需要出局{ printf("%d ",finger);//打印出局的人的编号 table[finger]=0;//将出局的人标号为0,表示不再参加报数cnt--;//参加报数的人 -- mouth = 0;//更新 mouth 的值} }return 0;}
谢谢观看!