约瑟夫问题最好使用的是循环表来做又简单,时间复杂度又不高而且好写好理解。
但是在殷人昆版的教科书中看到了用数组写的。思路又多了一些。
总结如下:
题目:试编写一个求解Josephus问题的函数。用整数序列1, 2, 3, ……, n表示顺序围坐在圆桌周围的人,并采用数组表示作为求解过程中使用的数据结构。然后使用n = 9, s = 1, m = 5,以及n = 9, s = 1, m = 0,或者n = 9, s = 1, m = 10作为输入数据,检查你的程序的正确性和健壮性。
图解:
我专门去文档上复制过来的 哈哈都给我看都给我学起来!
代码部分:
#include <stdlib.h>
#include <iostream>
void Josephus(int A[],int n,int s,int m){
int i,j,k,temp;
if(!m){
std::cerr<<"m=0是无效的参数"<<std::endl;
return;
}
for(i=0;i<n;i++)
A[i]=i+1;
i=(s-1+n)%n;
for(k=n;k>1;k--){
if(i==k)
i=0;
i=(i+m-1)%k;
if(i!=k-1){
temp=A[i];
for(j=i;j<k-1;j++)
A[j]=A[j+1];
A[k-1]=temp;
}
}
for(k=0;k<n/2;k++)
{
temp=A[k];
A[k]=A[n-k-1];
A[n-k-1]=temp;
}
}
int main() {
int n,s,m;
int A[15]={1,2,3,4,5,6,7,8,9};
std::cin>>n>>s>>m;
std::cout<<"n="<<n<<" "<<"s="<<s<<" "<<"m="<<m<<std::endl;
Josephus(A,n,s,m);
int *p=&A[0];
for(int i=0;i<10;i++){
std::cout<<A[i]<<std::endl;
}
return 0;
}
说明:
(1)教科书上的参考答案写错了一点,才开始的时候我用笔推敲半天都不行结果发现很傻呼呼的错误,在 for(k=n;k>1;k–)中它居然把k–写成i–,我是小白腊鸡斗不敢这样写哈哈哈。
(2)代码我是写了完整版的,加上的主函数,需要学习的同学可以看一下,直接拿我的跑c++就可以了,不用在此题上划过多的时间。