
5.5.4 用数学方法解约瑟夫环(1)上面编写的解约瑟夫环的程序模拟了整个报数的过程,程序运行时间还可以接受,很快就可以出计算结果。可是,当参与的总人数N及出列值M非常大时,其运算速度就慢下来。例如,当N的值有上百万,M的值为几万时,到最后虽然只剩2个人,也需要循环几万次(M的数量)才能确定2个人中下一个出列的序号。显然,在这个程序的执行过程中,很多步骤都是进行重复无用的循环。那么,能不能设计出更有效率的程序呢?办法当然有。其中,在约瑟夫环中,只是需要求出最后的一个出列者最初的序号,而不必要去模拟整个报数的过程。因此约瑟夫环 数学推导,为了追求效率,可以考虑从数学角度进行推算,找出规律然后再编写程序即可。为了讨论方便,先根据原意将问题用数学语言进行描述。问题:将编号为0~(N–1)这N个人进行圆形排列,按顺时针从0开始报数,报到M–1的人退出圆形队列,剩下的人继续从0开始报数,不断重复。求最后出列者最初在圆形队列中的编号。下面首先列出0~(N–1)这N个人的原始编号如下:根据前面曾经推导的过程可知,第一个出列人的编号一定是(M–1)%n。例如,在41个人中,若报到3的人出列,则第一个出列人的编号一定是(3–1)%41=2,注意这里的编号是从0开始的,因此编号2实际对应以1为起点中的编号3。

即,将出列1人后的数据重新组织成了1~n-1的列表,继续求n–1个参与人员,按报数到m即出列,求解最后一个出列者最初在圆形队列中的编号。关于列表的主要标记,如下表所示标记 描述

例如,设N=2,M=3(即2个人,报数到2时就出列),则按上式计算得到的值是:一共只有2人参与,编号为3的人显然没有。怎么办?由于是环状报数,因此当两个人报完数之后,又从编号为0的人开始接着报数。根据这个原理,即可对求得的值与总人数N进行模运算,即:5.5.4 用数学方法解约瑟夫环(2)即,N=2,M=3(即有2个人,报数到3–1的人出列)时,循环报数最后一个出列的人的编号为1(编号从0开始)。我们来推算一下,如下所示,当编号为0、1的两个人循环报数时,编号为0的人报的数为0和2,当报到2(M–1)时,编号0出列,最后剩下编号为1的人,所以编号为1的人最后出列。根据上面的推导过程,可以很容易推导出,当N=3时的公式:同理,也可以推导出参与人数为N时,最后出列人员编号的公式:其实,这就是一个递推公式,公式包含以下两个式子:有了这个递推公式,再来设计程序就很简单了,可以用递归的方法来设计程序,具体代码如下:#include<stdio.h>intmain(void){intn,m,i,s=0;printf('输入参与人数N和出列位置M的值=');scanf('%d%d',&n,&m);printf('最后出列的人最初位置是%d\n',josephus(n,m));getch();return0;}intjosephus(intn,intm){if(n==1)return0;elsereturn(josephus(n-1,m) m)%n;}在以上代码中,定义了一个递归函数josephus(),然后在主函数中调用这个函数进行 运算。
( bg-edit ) 当数控机床执行自动(auto)加工时,可同时输入或编写另一程序,而不需耍停止操作。2算法思想描述:2.1算法概述:建立一个循环单链表,然后输入要建立结点的个数,在每个结点输入一个密码,同时按输入时的顺序进行编号:1,2,3,4, ……n.任选一个正整数x作为初始报数上限值.从定义的那个头结点开始,数到x,输出该结点所储存的编号和密码.并将该密码作为新的x值,同时还将该密码所在的结点删除.如此循环链表还剩最后一个数据的时候停止此循环.再将最后一个没在循环里面的编号和密码另外输出.循环链表如图1所示:图22.2算法具体分析window ,switch ,upbar(), downbar(),key 这几个函数是构建本程序菜单所必须的函数.window 用于开窗口,以坐标的形式开辟一个窗口,并且可以在窗口里面储存数据.switch 创建菜单选项,key 主要用于获取键盘上的字符 包括字母和方向键,enter键 ,upbar 和 downbar 实现光条的上移和下移. textbackground ,textcolor 。(1)通过公式管理器编写条件选股公式,编写完后会在条件列表的下拉框中找到编写的条件选项股公式约瑟夫环 数学推导,先选择计算参数,然后点击“加入条件”,点击“执行选股”,就会自动的执行条件选股。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-104440-1.html
台湾同胞抗议台独
的瑟的很
自已弄点水果榨汁加点酒精加点水加点糖就好了