zoukankan      html  css  js  c++  java
  • 约瑟夫环:递归算法(唐伯虎点秋香)

    约瑟夫环:递归算法

     

    假设下标从0开始,0,1,2 .. m-1共m个人,从1开始报数,报到k则此人从环出退出,问最后剩下的一个人的编号是多少?

    现在假设m=10

    0 1 2 3  4 5 6 7 8 9    k=3

    第一个人出列后的序列为:

    0 1 3 4 5 6 7 8 9

    即:

    3 4 5 6 7 8 9 0 1(*)

    我们把该式转化为:

    0 1 2 3 4 5 6 7 8 (**)

    则你会发现: ((**)+3)%10则转化为(*)式了

    也就是说,我们求出9个人中第9次出环的编号,最后进行上面的转换就能得到10个人第10次出环的编号了 

    设f(m,k,i)为m个人的环,报数为k,第i个人出环的编号,则f(10,3,10)是我们要的结果

    当i=1时,  f(m,k,i) = (m+k-1)%m

    当i!=1时,  f(m,k,i)= ( f(m-1,k,i-1)+k )%m

    所以程序如下:

    int fun(int m,int k,int i){
     
        if(i==1)
            return (m+k-1)%m;
        else
            return (fun(m-1,k,i-1)+k)%m;
     
    }
    int main(int argc, char* argv[])
    {
         
        for(int i=1;i<=10;i++)
            printf("第%2d次出环:%2d
    ",i,fun(10,3,i));
        return 0;
    }
    第 1次出环: 2
    第 2次出环: 5
    第 3次出环: 8
    第 4次出环: 1
    第 5次出环: 6
    第 6次出环: 0
    第 7次出环: 7
    第 8次出环: 4
    第 9次出环: 9
    第10次出环: 3
    

     

        数学解(提供思路):

     

     参考C#做法(据说不是很好)

    常用算法(C#): 约瑟夫环问题
    约瑟夫环问题: 设有n个人围坐在圆桌周围,现从某个位置m(1≤m≤n)上的人开始报数,报数到k的人就站出来。
    继续下一个人,即原来的第k+1个位置上的人,又从1开始报数,再报数到k的人站出来。依此重复下去,直到全部的人都站出来为止
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace ExJose
    {
        class ClassJose    {
            //从第start人开始计数,以alter为单位循环记数出列,总人数为total 
            public int[] Jose(int total, int start,int alter)
            {
                int j, k = 0;
                //count数组存储按出列顺序的数据,以当结果返回 
                int[] count = new int[total + 1];
                //s数组存储初始数据 
                int[] s = new int[total + 1];
                //对数组s赋初值,第一个人序号为0,第二人为1,依此下去
                for (int i = 0; i < total; i++)
                {
                    s[i] = i;
                }
                //按出列次序依次存于数组count中 
                for (int i = total; i >= 2; i--)
                {
                    start = (start + alter - 1) % i;
                    if (start == 0)
                        start = i;
                    count[k] = s[start];
                    k++;
                    for (j = start + 1; j <= i; j++)
                        s[j - 1] = s[j];
                }
                count[k] = s[1];
                //结果返回 
                return count;
            }
            static void Main(string[] args)
            {
                ClassJose    e=new ClassJose     ();
                int[] a = e.Jose(10,3,4);
                for (int i = 0; i < a.Length; i++)
                {
                    Console.WriteLine(a[i].ToString ());
                }
            }
        }
    }
  • 相关阅读:
    c++小游戏——2048
    c++小游戏——贪吃蛇
    218 事件处理 on() 绑定事件
    217 jQuery 元素操作:遍历,创建,添加(append、prepend、after、before),删除(remove、empty、html)
    216 jQuery 文本属性值:html() 、text() 、 val()
    215 jQuery 属性操作:prop() 、 attr() 、 data()
    214 jQuery案例:王者荣耀手风琴效果
    213 jQuery 事件切换:hover()
    212 停止动画排队: stop()
    211 jQuery 自定义动画:animate()
  • 原文地址:https://www.cnblogs.com/zjfjava/p/5994437.html
Copyright © 2011-2022 走看看