首先,约瑟夫环的数学优化方法为:
为了讨论方便,先把问题稍微改变一下,并不影响原意:问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
我们知道第一个人(编号一定是(m-1)%n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始): k k+1 k+2 ... n-2, n-1, 0, 1, 2, ... k-2 并且从k开始报0。现在我们把他们的编号做一下转换:
k --> 0 k+1 --> 1 k+2 --> 2
n-1 --> n-1-k 0--> n-k
... ...
k-3 --> n-3 k-2 --> n-2
序列1: 1, 2, 3, 4, …, n-2, n-1, n
序列2: 1, 2, 3, 4, … k-1, k+1, …, n-2, n-1, n
序列3: k+1, k+2, k+3, …, n-2, n-1, n, 1, 2, 3,…, k-2, k-1
序列4:1, 2, 3, 4, …, 5, 6, 7, 8, …, n-2, n-1
变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:
∵ k=m%n;
∴ x' = x+k = x+ m%n ; 而 x+ m%n 可能大于n
∴x'= (x+ m%n)%n = (x+m)%n 得到 x‘=(x+m)%n
如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:
令f表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n].
递推公式: f[1]=0; f[i]=(f[i-1]+m)%i; (i>1)
完整的实现代码如下:
/*
约瑟夫环递推公式:令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式 f[1]=0; f[i]=(f[i-1]+m)%i; (i>1)
*/
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
int n, m,i, f[20]={0};
scanf("%d %d",&n,&m);
for(i=2;i<=n;i++)
{
f[i]=(f[i-1]+m)%i;
printf("%d个人报数,报到%d的出列,最后的胜者下标为%d\n", i,m,f[i]);
}
printf("The winner is %d\n", f[n]+1);
system("pause");
}
优化后的代码为:
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
int n, m,i, s=0;
scanf("%d %d",&n,&m);
for(i=2;i<=n;i++)
{
s=(s+m)%i;
}
printf("The winner is %d\n", s+1);
system("pause");
}
分享到:
相关推荐
在原始的约瑟夫环的要求下增加一限制:一共有n个人组成环(n=2∗k),前k个是好人,后k个是坏人,即编号1~k是好人,k+1~2k是坏人。要求在第一个好人出局之前,所有的坏人都已经出局。
约瑟夫环问题是典型的线性表的应用实例,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而对于后者则要求应用程序功能完备,易...
这个就是约瑟夫环问题的实际场景,后来老师要求我们对要求中的每人所持有的密码以及第一次的报数上限值要用随机数产生。因此约瑟夫环问题如果采用双向循环链表则能很好的解决。循环链表的数据结构,就是将一个链表的...
这个约瑟夫环用了好多函数 但看起来通俗易懂 可以有自己选择输入几个人 又可以决定那些人死亡 实现的简单 适合初学者的题目 当然可以改进了这由你自己决定啦
资源由个人整理修改得出,仅供学习交流使用……
这是我学完链表后写的 不一定很完整 希望大家参考后能进一步改进 顺便告诉我哦!!!
在上交资料中请写明:存储结构、多项式相加的基本过程的算法(可以使用程序流程图) 、源程序、测试数据和结果、算法的时间复杂度、另外可以提出算法的改进方法。 题目 3 迷宫求解 1、问题描述 可以输入一个任意大小...
最后,通过使用改进的约瑟夫斯环(Josephus ring)对被遮挡图像的位置进行加密以获得加密图像。 根据实验,加密图像的信息熵达到7.99,三个方向的相邻相关度在±0.1以内。 实验结果表明,该算法具有密钥空间大,...
| 约瑟夫环问题(数学方法) 27 | 约瑟夫环问题(数组模拟) 27 | 取石子游戏 1 27 | 集合划分问题 27 | 大数平方根(字符串数组表示) 28 | 大数取模的二进制方法 28 | 线性方程组 A[][]X[]=B[] 28 | 追赶法...
7.4 约瑟夫环 7.5 二进制/八进制转换器 7.6 回文字符串的判定 7.7 括号匹配 7.8 魔王语言翻译 7.9 动态双向链表的应用 7.10 判断完全二叉树 7.11 动画模拟创建二叉树 7.12 打印符号三角形 7.13 递归函数的非递归...
ZJU_Main 主页 下一页 ZJU 题型分类 文演整理版 2008-3-23 数论: 1007 Numerical Summation of a Series 简单题,还是蛮有意思的 1045 HangOver 简单题 ... 1049 I Think I Need a Houseboat 简单题 ...
ZJU 题型分类 ZJU_Main 主页 下一页 ZJU 题型分类 文演整理版 2008-3-23 数论: 1007 Numerical Summation of a Series 简单题,还是蛮有意思的 ... 1049 I Think I Need a Houseboat 简单题 ...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...