程序员面试金典——番外篇之约瑟夫问题1

Solution1:我的答案。脑子是个好东西,希望我总是带着他~
该算法模拟了游戏过程,不算好。
要理清逻辑关系,因果关系,再下笔~

class Joseph {
public:int getResult(int n, int m) {// write code hereif(n <= 0 || m <= 0)return -1;vector<bool> temp(n, false);int index = 0, count_m = 0, nums_false = n;while(1) {if(temp[index] == true) index = (index + 1) % n;else {count_m++;if(count_m == m) {temp[index] = true;nums_false--;if(nums_false == 0)return index + 1;//这,就是答案!else {count_m = 0;index = (index + 1) % n;}}else index = (index + 1) % n;}}return -1;}
};

Solution2:小技巧啊~
参考网址:https://www.nowcoder.com/profile/5263754/codeBookDetail?submissionId=13380131
思路:求出了递推公式,真牛逼
把n个人的编号改为0~n-1,然后对删除的过程进行分析。
第一个删除的数字是(m-1)%n,记为k,则剩余的编号为(0,1,…,k-1,k+1,…,n-1),下次开始删除时,顺序为(k+1,…,n-1,0,1,…k-1)。
用f(n,m)f(n,m)f(n,m)表示从(0~n-1)开始删除后的最终结果。
用q(n−1,m)q(n−1,m)q(n-1,m)表示从(k+1,…,n-1,0,1,…k-1)开始删除后的最终结果。
则f(n,m)=q(n−1,m)f(n,m)=q(n−1,m)f(n,m)=q(n-1,m)。

下面把(k+1,…,n-1,0,1,…k-1)转换为(0~n-2)的形式,即
k+1对应0
k+2对于1

k-1对应n-2
转化函数设为p(x)=(x−k−1)%np(x)=(x−k−1)%np(x)=(x-k-1)\%n, p(x)p(x)p(x)的逆函数为p−1(x)=(x+k+1)%np−1(x)=(x+k+1)%np^{-1}(x)=(x+k+1)\%n。
则f(n,m)=q(n−1,m)=p−1(f(n−1,m))=(f(n−1,m)+k+1)%nf(n,m)=q(n−1,m)=p−1(f(n−1,m))=(f(n−1,m)+k+1)%nf(n,m)=q(n-1,m)=p^{-1}(f(n-1,m))=(f(n-1,m)+k+1)\%n,又因为k=(m−1)%nk=(m−1)%nk=(m-1)\%n。
f(n,m)=(f(n−1,m)+m)%nf(n,m)=(f(n−1,m)+m)%nf(n,m)=(f(n-1,m)+m)\%n;

最终的递推关系式为

f(1,m)=0;(n=1)f(1,m)=0;(n=1)

f(1,m) = 0; (n=1)

f(n,m)=(f(n−1,m)+m)%n;(n>1)f(n,m)=(f(n−1,m)+m)%n;(n>1)

f(n,m)=(f(n-1,m)+m)\%n; (n>1)
代码如下

class Joseph {
public:int getResult(int n, int m) {// write code here   int pre = 0;for (int i = 2; i <= n; i++) {pre = (pre + m)%i;}return pre + 1;}
};

程序员面试金典——番外篇之约瑟夫问题1相关推荐

  1. 程序员面试金典——番外篇之约瑟夫问题2

    程序员面试金典--番外篇之约瑟夫问题2 参考网址:https://www.nowcoder.com/profile/9270572/codeBookDetail?submissionId=157791 ...

  2. 程序员面试金典——番外篇之下一个较大元素II

    程序员面试金典--番外篇之下一个较大元素II Solution1:我的答案,时间复杂度为O(n2)O(n2)O(n^2) 垃圾算法 class NextElement { public:vector& ...

  3. 程序员面试金典——番外篇之下一个较大元素I

    程序员面试金典--番外篇之下一个较大元素I Solution1:我的答案,时间复杂度为O(n2)O(n2)O(n^2) 垃圾算法 class NextElement { public:vector&l ...

  4. 【重点】程序员面试金典——番外篇之数组中的逆序对

    程序员面试金典--番外篇之数组中的逆序对 此题曾多次遇到,然鹅还是本能的想起来复杂度为O(n2)O(n2)O(n^2)的笨蛋方法... Solution1:笨蛋方法 class AntiOrder { ...

  5. 【To Understand】程序员面试金典——番外篇之洪水

    程序员面试金典--番外篇之洪水 参考网址:https://www.nowcoder.com/profile/1917743/codeBookDetail?submissionId=12679910 S ...

  6. 程序员面试金典--笔记(精华篇)

    原文链接:http://codeshold.me/2017/01/cracking_interview.html <程序员面试金典> 1-7章的总结 相关读物<金领简历:敲开苹果.微 ...

  7. 《程序员面试金典》+《算法导论》

    <程序员面试金典>+<算法导论> 因为最近可能会面临一波面试,但是自己各种算法以及常见的问题的熟悉程度感觉还不够,但是由前几次的代码优化经验来看,算法优化可以说是代码优化的重中 ...

  8. C#LeetCode刷题-程序员面试金典

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#LeetCode刷题-程序员面试金典 | .Net中文网. C#LEETCODE刷题概述 概述 所有LeetCode程序员面试金典 ...

  9. 《程序员面试金典(第6版)》面试题 16.13. 平分正方形(直线的斜截式方程,C++)

    题目描述 给定两个正方形及一个二维平面.请找出将这两个正方形分割成两半的一条直线.假设正方形顶边和底边与 x 轴平行. 每个正方形的数据square包含3个数值,正方形的左下顶点坐标[X,Y] = [ ...

最新文章

  1. 皮一皮:论蓝朋友的拍摄技术
  2. jackson.ObjectMapper里enableDefaultTyping方法过期
  3. 01需求工程-软件建模与分析阅读笔记
  4. Hadoop精华问答 | NameNode是什么?
  5. 轻松理解Spring框架的基本思想
  6. 自行更换iPhone 13屏幕会导致Face ID失效?苹果将发布软件更新解除限制
  7. 为什么要Code Review
  8. ubuntu 下 apache2 查看 已加载的模块 命令
  9. 抽象代数学习笔记(抽象代数的历史、运算)
  10. 心理学在游戏设计中的作用
  11. r型聚类典型指标_SPSS聚类分析经典案例分享
  12. 第6堂视频课:看到词句就会读-下
  13. 此时不应有 \Common
  14. 什么是cert文件?
  15. SRT视频字幕的解析与同步原理
  16. AVS3变换系数编码:SRCC
  17. socket中的read返回0
  18. 全国计算机考试cad,国家CAD考试CAD试题库.pdf
  19. ROS2-foxy详细安装教程及相关问题的解决方法
  20. 蓝牙网状网络的基本原理及应用开发

热门文章

  1. [原创]c# 加解密通用类
  2. Learning Video Object Segmentation from Static Images
  3. xp 系统 mysql日志文件在哪里_SqlServer修改数据库文件及日志文件存放位置教程
  4. android scalex中心,androidmatrix android怎么算matrix中心点
  5. tinyint数据类型php筛选时怎么判断_PHP从入门到精通(三)PHP语言基础
  6. cenyos7安装 yum不可用_centos7安装fabric
  7. 间接寻址级别不同_「计算机组成原理」:常见的指令寻址方式
  8. jquery中each_如何在jQuery中使用each()
  9. python字符串 切片_Python切片字符串
  10. android 开发套件_Android套件