无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百 万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效 率,就要打破常规,实施一点数学策略。

为了讨论方便,先把问题稍微改变一下,并不影响原意:
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的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

...

...

k-2   --> n-2

k-1   --> n-1

变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k)%n

如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:

令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]

递推公式

f[1]=0;

f[i]=(f[i-1]+m)%i;  (i>1)

有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1

由于是逐级递推,不需要保存每个f[i],程序也是异常简单:

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;int main()
{char ch[30005];string s;int N=1999;int num,len;while(gets(ch)){s+=ch;}num=0;len=s.length();for(int i=2;i<=len;i++)num=(num+N)%i;if(s[num]=='?')printf("Yes\n");else if(s[num]==' ')printf("No\n");elseprintf("No comments\n");return 0;
}

poj 2359 约瑟夫环数学问题相关推荐

  1. UVA1363 LA3521 POJ2800 ZOJ2646 Joseph‘s Problem【约瑟夫环+数学】

    Joseph's Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7906 Accepted: 2107 Desc ...

  2. UVA1394 LA3882 POJ3517 And Then There Was One【约瑟夫环+数学】

    And Then There Was One Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5973 Accepted: 326 ...

  3. 约瑟夫环数学递推公式及其证明

    对于约瑟夫问题,今天看到了一篇好帖子,是用数学方法处理的,感觉还不错的无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂 度高达O(nm),当n,m非 ...

  4. UVA11351 Last Man Standing【约瑟夫环+数学】

    There are n people standing in a circle waiting to be executed. Starting from the first man, k−1 peo ...

  5. UVA 1394 And Then There Was One 约瑟夫环数学方法

    题意: n个人围成环,首先第m个人出列,然后从下一个开始,数到第k个就出列...问最后剩下的是谁? 为了方便,我们采用0~n-1的编号方式 先考虑当题意没有m的时候,就是说从第一个人开始,第k个人出列 ...

  6. 力扣1823题:找出游戏获胜者(约瑟夫环)

    本题刚开始我还在用数组去模拟删除,结果发现队列更简单: import java.util.ArrayDeque; import java.util.Queue; import java.util.Sc ...

  7. 约瑟夫环问题 —— 算法

    约瑟夫环问题 前言 约瑟夫环问题一 约瑟夫环问题二 约瑟夫环问题三 约瑟夫环问题四 约瑟夫环问题五 约瑟夫环问题六 约瑟夫环问题七 约瑟夫环问题解决一 -- 模拟队列 约瑟夫环问题解决二 -- 环形链 ...

  8. 约瑟夫环的数学优化方法

    首先,约瑟夫环的数学优化方法为: 为了讨论方便,先把问题稍微改变一下,并不影响原意:问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号 ...

  9. 约瑟夫环-(数组、循环链表、数学)

    约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出 ...

  10. 求约瑟夫环问题最后胜利者的一般解法以及数学推导方法

    问题描述: 约瑟夫环问题(Josephus) 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序. 解法一: 思路:建立一个有N个元素的循环链表,然后从链表表头遍 ...

最新文章

  1. 本地文件与服务器传输,云服务器 与本地文件传输
  2. 矛与盾:二进制漏洞攻防思想对抗
  3. 前端html继承的方式,好程序员web前端教程之JS继承实现方式解析
  4. (转载) min()的宏定义中的(void) (_x == _y)的含义
  5. 不知道从哪里开始更新你的秋季海报设计?
  6. 张鹏 html 笔记,传智 张鹏 html+css 课程 笔记2(吐血整理)
  7. 云计算学习笔记---异常处理---hadoop问题处理ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.lang.NullPoin
  8. python操作库_python操作数据库
  9. 元素定位(d4-2)
  10. chrome 截长图功能
  11. torch 矩阵运算
  12. Win10 快速检查修复系统方法
  13. 中文名颜色大全,妈妈再也不担心我找不着好颜色了.
  14. OpenGL立方体纹理贴图
  15. CentOS6.8 切换桌面模式与命令行模式
  16. C语言编棱,2009计算机二级C语言:C语言棱形图案写法
  17. GPT-4和ChatGPT的区别
  18. sqlite数据库加锁提交_如何解锁SQLite数据库?
  19. 天载股票资讯白酒等抱团股反攻
  20. 零基础搭建电影网站教程——二、运行环境

热门文章

  1. iPhone照片删除了怎么恢复?宝藏方法分享!
  2. 【打开网页一片空白 可以上Q却不能上网】firefox无法在XXX找到该服务器的真相
  3. JavaScript系列学习笔记1 —— 字符串和数值对象
  4. 奥运门票翻倍转让监管亮剑网络交易
  5. 免备案服务器会影响网站排名和权重吗?
  6. knife4j nacos聚合 请求文档异常
  7. knife4j 接口文档的使用-伟子涵Java
  8. 校内网开放平台 欲打造中国版Facebook
  9. 如何成为一个优秀SEO内容原创作者
  10. 全球与中国连续纤维增强热塑性复合材料市场销售现状及投资趋势分析报告2022-2028年