• 约瑟夫环问题


    约瑟夫环问题,是经典的算法题。百度百科解释如下

    约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。

    解决方案很多种,不过我都看不太懂(原谅我实在太愚笨了)

    这里我先举个例子

    假如 有5个人 数到3的要出列,那么过程是这样的

    开始是

    1  2  3  4  5

    毫无疑问 从1开始数,3号肯定要离开 得到

    1  2  4  5

    然后该4开始数了,那么数到5 再轮回头数 1要离开 得到

    2  4  5

    然后该2开始数,数到5  5离开 得到

    2  4

    然后发现5离开了后面轮回来还是2 那就还是2开始数 数回自己 自己离开 得到

    4

    整个过程就是 3离开 1离开 5离开 2离开 4留了下来

    如果转换为代码怎么实现呢?

    代码如下:

    <?php
    function joseph_problem($total=1,$number=1)
    {
        $array=range(1, $total);//把这些人都存入数组
        $start=0;//开始数数的第一个人的位置
        while (count($array)>1)
        {
            //说明里面还有人
            $need_del = ($start  + $number - 1) % count($array);
            if(isset($array[$need_del]))
            {
                echo "now need to del ".$array[$need_del]."<br/>";
                unset($array[$need_del]);
            }else
            {
                break;
            }
            $array=array_values($array);//形成新的数组
            $now_count = count($array);
            //计算出在新的$array中,开始报数的位置
            if($need_del>=$now_count)
            {
                $start=$need_del%$now_count;//如果需要删除的键大于了目前的总数量 说明要轮回开头 需要进行取余
            }else
            {
                $start=$need_del;//说明人还很多 那个人出列后 下一个开始位置就是它出列的那个键
            }
        }
        return $array[0];
    }
    echo joseph_problem(5,3);exit();
    ?>

    截图如下:

    输出效果如下:

  • 相关阅读:
    CF960G-Bandit Blues【第一类斯特林数,分治,NTT】
    P6122-[NEERC2016]Mole Tunnels【模拟费用流】
    P5404-[CTS2019]重复【KMP,dp】
    P5405-[CTS2019]氪金手游【树形dp,容斥,数学期望】
    T183637-变异距离(2021 CoE III C)【单调栈】
    61-A
    2021-4-1考试
    JAVA日常练习—程序输入string转化为int并求和
    并发编程
    git clone 报filename too long 错误的解决方法
  • 原文地址:https://www.cnblogs.com/lizhaoyao/p/7463670.html
Copyright © 2020-2023  润新知