约瑟夫环问题
问题描述] 编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。 [基本要求] 利用顺序存储结构模拟此过程,按照出列的顺序输出各个人的编号。
//顺序结构实现 #include <iostream.h> #include <math.h> void main() { int n,b,m; //从数组的第b个元素开始报://报到m的人出列; int A[]={1,2,3,4,5,6,7,8}; //数组A[]用来盛放原序列; int B[8]; //数组B[]用来盛放出列的元素 n=8; //数组长度为8; cout<<"输入开始报数位置 b :"; cin>>b; cout<<"输入出列口令 m :"; cin>>m; cout<<"原序列为 :"; for(int i=0;i<n;i++) cout<<A<<" "; cout<<endl; i=0; //变量i用作数组B[]的下标; b=(b+m-2)%n; //b的意义在此改变,它表示在数组A[]中下标为b的位置上的元素出列; while(i<n) //做循环。负责把数组A[]中报m的元素都出列; { B=A; i++; if(i==n){ //这一句在B[]满时才执行,负责打印出队序列; cout<<"出队序列为:"; for(i=0;i<n;i++) cout<<B<<" "; return; } else { A=0; //作标记; b=(b+1)%n; int p=1; while(p<m) //负责找到出队元素前有(m-1)个非零元素; { if (A==0) b=(b+1)%n; else { b=(b+1)%n; p++; } } } while(A==0) //负责找到当前下一个不为零的元素,为下一次出列做准备; b=(b+1)%n; } }
|