数学思想可以极大的节省编程所耗费的时间和空间,抛去数学思想的约瑟夫问题实质上就是对整个过程的模拟,可以用数组或者循环链表解决。
而在网上看到几篇论文阐述了报长为定数的约瑟夫问题的数学解法,但是在论文中却提到认为报数长度不定的约瑟夫问题是不能用数学思想的,这是不对的,其实两者本质上是一样的,我们只要用一个数组来储存每次报数的长度就行,下面给出递归解法的代码。
//返回的位置是以0开始计算的
int Josephues(int *Jose,int *num,int len)
{
if(len==1)
return 0;
else
{
int x=(Josephues(Jose,num,len-1)+num[len-2])%len;
return x;
}
}
//满足下列关系式子
//f[n]=(f[n-1]+num[n-2])%n
//其中数组num[n-1]代表还剩下n个人时报的数字
//f[n]表示目标解在还有n个人时中的位置
//一个例子
//0,1,2,3,...,num[n-2]-2,num[n-2]-1,
num[n-2],...,n-2,n-1
//去掉第num[len-2]个元素后
//0,1,2,3,...,num[n-2]-2, ,
num[n-2],...,n-2,n-1
//从num[len-2]又组成一个新的约瑟夫环
//旧环:
//num[len-2],num[n-2]+1,...,n-2,
n-1,0,1,2,3,..,num[n-2]-2
//新环:
//0,1,...n-2-num[n-2],
n-1-num[n-2],n-num[n-2]...,n-2;
//若是新环的解是x'
//那么便可以计算出在他上一层解的位置
//x=(x'+num[n-2]%n)%n