【生活处处皆算法】巧用约瑟夫环

1、描述

约瑟夫环(约瑟夫问题)是一个数学的应用问题:

已知n个人(以编号1,2,3....n分别表示)围坐在一张圆桌周围。

从编号为k的人开始报数,数到m的那个人出圈;他的下一个人又从1开始报数,数到m的那个人又出圈;依次规律重复下去,直到剩余最后一个胜利者。

例如:有10个人围成一圈进行此游戏,每个人编号为1-10。若规定数到3的人出圈。则游戏过程如下:

(1) 开始报数,第一个数到3的人为3号,则3号出圈

        1,2,【3】,4,5,6,7,8,9,10

(2) 从4号重新从1开始计数,则接下来数到3的人为6号,6号出圈

        1,2,【3】,4,5,【6】,7,8,9,10

(3) 从7号重新从1开始计数,则接下来数到3的人为9号,则9号出圈

        1,2,【3】,4,5,【6】,7,8,【9】,10

(4) 从10重新从1开始计数,由于10个人称环形结构,则接下来数到3的人为2号,2号出圈

        1,【2】,【3】,4,5,【6】,7,8,【9】,10

(5) 从4号重新从1开始计数,则接下来数到3的人为7号,7号出圈

        1,【2】,【3】,4,5,【6】,【7】,8,【9】,10

(6) 从8号重新从1开始计数,则接下来数到3的人为1号,1号出圈

        【1】,【2】,【3】,4,5,【6】,【7】,8,【9】,10

(7) 从4号重新从1开始计数,则接下来数到3的人为8号,8号出圈

        【1】,【2】,【3】,4,5,【6】,【7】,【8】,【9】,10

(8) 从10重新从1开始计数,则接下来数到3的人为5号,5号出圈

        【1】,【2】,【3】,4,【5】,【6】,【7】,【8】,【9】,10

(9) 从10重新从1开始计数,则接下来数到3的人为10,10号出圈

        【1】,【2】,【3】,4,【5】,【6】,【7】,【8】,【9】,【10】

(10) 最终剩余4号,4号为胜利者

2 求解

2.1 数组求解-解题思想

        用数组求解的基本思想就是用一个数组去标识这n个人的状态,默认全为1,也就是都在圈子内。

        当数到m的人出圈之后,标识置为0(就是出圈了),同时报数器清0,下一个要从1开始。

        在每次报数之前要判断他是否在圈子内(也就是他的标识是否为1),如果在圈子里面才会继续报数。定义一个变量记录出圈的人数,出圈            的人数等于n-1时,则游戏结束。

        public function joseph($n, $m) {
            $flag = [];
            for($i = 1; $i <= $n; $i++) {
                    $flag[$i] = 1;
            }
            // 计数器
            $num = 0;
            // 统计出圈的次数
            $count = 0;
            while($count < $n - 1) {
                    for($i = 1; $i <=$n; $i++) {
                            if($flag[$i] == 1) {
                                    $num++;
                                    if($num == $m) {
                                            $num = 0;
                                            $count++;
                                            $flag[$i] = 0;
                                    }
                                    if($count == $n - 1) {
                                              break;
                                    }
                            }
                    }
            }
            for($i = 1; $i <= $n; $i++) {
                    if($flag[$i] == 1) {
                        echo "The last one is:".$i;
                    }
            }
        }

你可能感兴趣的:(【生活处处皆算法】巧用约瑟夫环)