算法4中的Josephus问题

来源:互联网 发布:windows内核启动过程 编辑:程序博客网 时间:2024/05/20 08:01

题目:Josephus问题:在古老的问题中, N个身陷绝境的人一致同意通过以下方式减少生存人数。他们围坐一圈(位置记为0到N-1)并从第一个人开始报数,报到M的人会被杀死,直到最后一个人留下来。传说中Josephus找到了不会被杀死的位置。编写一个Queue的用例Josephus,从命令行接受N和M并打印出被杀死的顺序(这也将显示Josephus在圈中的位置)

% java Josephus 7 2

1 3 5 0 4 2 6

public class Josephus {    public static void main(String[] args) {        int m = Integer.parseInt(args[0]);        int n = Integer.parseInt(args[1]);        // initialize the queue        Queue<Integer> queue = new Queue<Integer>();        for (int i = 0; i < n; i++)            queue.enqueue(i);        while (!queue.isEmpty()) {            for (int i = 0; i < m-1; i++)//每M个人中,去掉最后一名(即第M名),所以将前M-1个人放在队尾,删掉第M个人。
                queue.enqueue(queue.dequeue());            StdOut.print(queue.dequeue() + " ");        }         StdOut.println();//最后一个输出的数就是Josephus在队中的位置    }}

约瑟夫问题的数学分析:
转载:数学归纳法分析

对于公式F(n) = [F(n-1) + M] % n的分析

在前n-1个人中已经找到最后一个出列的,即前n-1个人中最后一个出列的喊的数字是M-1,那么n个人中最后一个人喊的数字应该为M。%n是为了避免F(n-1)+M大于n。

#include <stdio.h> int main(void)  {      int n,m,i,s=0;      printf ("输入参与人数N和出列位置M的值 = ");      scanf("%d%d",&n,&m);            printf ("最后出列的人最初位置是 %d\n",josephus(n,m));      getch();      return 0 ;  }   int josephus(int n,int m)  {      if(n==1)          return 0;      else          return (josephus(n-1,m)+m)%n;  }  在以上代码中,定义了一个递归函数josephus(),然后在主函数中调用这个函数进行   运算。

使用递归函数会占用计算机较多的内存,当递归层次太深时可能导致程序不能执行,因此,也可以将程序直接编写为以下的递推形式: #include <stdio.h> int main(void)  {      int n,m,i,s=0;      printf ("输入参与人数N和出列位置M的值 = ");      scanf("%d%d",&n,&m);      for (i=2; i<=n; i++)          s=(s+m)%i;      printf ("最后出列的人最初位置是 %d\n",s);      getch();      return 0 ;  }  这段代码执行的结果与递归程序执行结果完全相同。


0 0
原创粉丝点击