joseph问题-北航的一个ACM题目

本文介绍了如何利用中国剩余定理解决北航ACM竞赛中的约瑟夫问题。在有k个好人和k个坏人的情况下,寻找最小的m,使得所有坏人在不伤害好人的前提下被依次淘汰。关键在于确定a[i]的最小值,其中a[1]=k+1,a[i]=1(i=2,...,k),通过计算公式找到满足条件的m。" 129316510,17295695,Java架构进阶:设计模式+Spring源码+MyBatis解析,"['Java', 'Spring框架', 'MyBatis框架', '设计模式', '源码阅读']
摘要由CSDN通过智能技术生成

 

 

 

问题:

 

我们都知道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:

第一步和第二部中的字母没有协调好,凑合的看吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值