poj 2359 约瑟夫环数学问题
无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达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 约瑟夫环数学问题相关推荐
- UVA1363 LA3521 POJ2800 ZOJ2646 Joseph‘s Problem【约瑟夫环+数学】
Joseph's Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7906 Accepted: 2107 Desc ...
- UVA1394 LA3882 POJ3517 And Then There Was One【约瑟夫环+数学】
And Then There Was One Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5973 Accepted: 326 ...
- 约瑟夫环数学递推公式及其证明
对于约瑟夫问题,今天看到了一篇好帖子,是用数学方法处理的,感觉还不错的无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂 度高达O(nm),当n,m非 ...
- UVA11351 Last Man Standing【约瑟夫环+数学】
There are n people standing in a circle waiting to be executed. Starting from the first man, k−1 peo ...
- UVA 1394 And Then There Was One 约瑟夫环数学方法
题意: n个人围成环,首先第m个人出列,然后从下一个开始,数到第k个就出列...问最后剩下的是谁? 为了方便,我们采用0~n-1的编号方式 先考虑当题意没有m的时候,就是说从第一个人开始,第k个人出列 ...
- 力扣1823题:找出游戏获胜者(约瑟夫环)
本题刚开始我还在用数组去模拟删除,结果发现队列更简单: import java.util.ArrayDeque; import java.util.Queue; import java.util.Sc ...
- 约瑟夫环问题 —— 算法
约瑟夫环问题 前言 约瑟夫环问题一 约瑟夫环问题二 约瑟夫环问题三 约瑟夫环问题四 约瑟夫环问题五 约瑟夫环问题六 约瑟夫环问题七 约瑟夫环问题解决一 -- 模拟队列 约瑟夫环问题解决二 -- 环形链 ...
- 约瑟夫环的数学优化方法
首先,约瑟夫环的数学优化方法为: 为了讨论方便,先把问题稍微改变一下,并不影响原意:问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号 ...
- 约瑟夫环-(数组、循环链表、数学)
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出 ...
- 求约瑟夫环问题最后胜利者的一般解法以及数学推导方法
问题描述: 约瑟夫环问题(Josephus) 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序. 解法一: 思路:建立一个有N个元素的循环链表,然后从链表表头遍 ...
最新文章
- 本地文件与服务器传输,云服务器 与本地文件传输
- 矛与盾:二进制漏洞攻防思想对抗
- 前端html继承的方式,好程序员web前端教程之JS继承实现方式解析
- (转载) min()的宏定义中的(void) (_x == _y)的含义
- 不知道从哪里开始更新你的秋季海报设计?
- 张鹏 html 笔记,传智 张鹏 html+css 课程 笔记2(吐血整理)
- 云计算学习笔记---异常处理---hadoop问题处理ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.lang.NullPoin
- python操作库_python操作数据库
- 元素定位(d4-2)
- chrome 截长图功能
- torch 矩阵运算
- Win10 快速检查修复系统方法
- 中文名颜色大全,妈妈再也不担心我找不着好颜色了.
- OpenGL立方体纹理贴图
- CentOS6.8 切换桌面模式与命令行模式
- C语言编棱,2009计算机二级C语言:C语言棱形图案写法
- GPT-4和ChatGPT的区别
- sqlite数据库加锁提交_如何解锁SQLite数据库?
- 天载股票资讯白酒等抱团股反攻
- 零基础搭建电影网站教程——二、运行环境