问题:
我们都知道joseph 问题,n 个人围成一圈以m 报数,报m 的人被杀死,余下来的人接着从1 报数,直到剩最后一人。
现在我们已知有k 个好人,k 个坏人,(1 <=k <=14 )围成一圈报数,前k 个为好人,后k 个为坏人,求最小的m 使得所有的坏人先被杀死( 保证不死一个好人的情况)
来源: 北航的一个ACM 题目---- 约瑟夫,求快速的解法!!! (oyzdz1988 )
解答:
解决方案为中国剩余定理。
1.
中国剩余定理
a)
简介:
中国剩余定理 是指若有一些两两复质的整数m[1],m[2],…m[n] ,则对任意的整数:a[1],a[2],…,a[n] ,以下联立同余方程组对模 m[1],m[2],…,m[n] 有公解:
X=a[i] mod m[i] (i=1,…,n)
那么X 有小于 m[1]*m[2]*…*m[n] 的唯一解。
b)
X 的计算方法
假设M= m[1]*m[2]*…*m[n] , 那么 k[i]=M/m[i] , 计算l[i], 使得 k[i]*l[i]=1 mod m[i]
X=( a[1]*k[1]*l[1] + …+ a[n]*k[n]*l[n] ) mod M
2.
中国剩余定理在该题的应用
显然m 满足如下要求
m=a[1] mod 2k
m=a[2] mod (2k-1)
…
m=a[k] mod (k+1)
由于 2k , 2k-1 ,…, k+1 两两复素,可以使用中国剩余定理(显然,不予证明)
注意到中国剩余定理的计算公式
X= ( a[1]*k[1]*l[1] + …+ a[n]*k[n]*l[n] ) mod M
其中当好人个数k 给定时, k[i]*l[i] (i=1,…,n) 都固定,要得到m 的大小只和 a[i] 相关。要计算最小的m ,只需要的到最小的一组 a[i] ,但是由于条件中限制不能杀死一个好人,因此 a[i] 有一定的取值防范,这就是该题难点。
根据该题的题意有 a[i] >0, 所以 a[i] 最小为1 ,这就是该题的突破点,若能够让 a[i] =1 或取值范围中的最小值,就能够保证m 最小。
结论:
1)
a[1]=k+1 ,第一步最小取值
2)
a[i]=1 (i=2,…,k) , 最小值
既,杀死坏人的顺序为 k+1,k+2,k+3,…,2k 。
步骤如下:杀死编号为k+1 的坏人,那么编号为k+2 的坏人此时从1 开始报数,若m mod (2k-1 ) =1 ,该坏人被杀死,以此类推。
Ps:
第一步和第二部中的字母没有协调好,凑合的看吧