N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。
Input
2个数N和K,表示N个人,数到K出列。(2 <= N, K <= 10^6)
Output
最后剩下的人的编号
Input示例
3 2
Output示例
3
解:

 #include <stdio.h>
int main()
{
int n, k;
while (scanf_s("%d%d", &n, &k) != EOF)
{
int move = ;
for (int i = ; i <= n; i++) move = (move + k) % i;
printf("%d\n", move + );
}
}

首先,我是从正向思考,即找出每次去掉的元素,并标记,循环n-1次,最后找到未标记的元素即可。这个思路简单,但实现却麻烦。
然后,是用链表的删改来完成游戏成员的淘汰,删除n-1个节点,最后剩余的就是winner。但这仍不够简单。
最后,注意到约瑟夫环的环状结构的特性,使我们可以利用当k为相同值时,n-1个人玩游戏和n个人玩游戏存在的数学关系解决问题。
这种数学关系简单叙述如下:
n个人玩游戏,k为常数,定义f(n)为n人游戏时的胜利者编号。第一轮淘汰者为(k-1)%n+1(为什么不是k%n?注意取模运算的范围为[0,n-1],考虑k=n的情况),之后我们可以将(k-1)%n+2作为新的排头head,(k-1)%n为尾tail,以另一种方式展开这个环。
由于head=1,tail=n-1时,winner=f(n-1),
则head=(k-1)%n+2,tail=(k-1)%n时,winner=winner+(k-1)%n+1。(考虑到加法中可能存在的“溢出”问题,将公式标准化如下)

winner=f(n-1)+(k-1)%n+1-1)%n+1=(f(n-1)+(k-1)%n)%n+1=(f(n-1)+k-1)%n+1。

所以我们得到递推公式如下:
定义f(n)为n人游戏时的胜利者编号,k由题目定义,
则 f(1)=1;
  f(n)=(f(n-1)+k-1)%n+1;
由于取模运算的范围包括零,所以我们在运算前要-1,运算后要+1。那我们可不可以将这个步骤省略呢?
我们需要改变f(n)的定义,即将f(n)定义为f(n)-1(其实这时候的f(n)可以理解为偏移量,它的值代表的是n人游戏时获胜者的相对于零位置的位置),
所以递推公式化简为:f(1)=0;
          f(n)=(f(n-1)+k)%n;(最终答案不要忘记+1!)

(数论)51NOD 1073 约瑟夫环的更多相关文章

  1. 51nod 1073 约瑟夫环

    题目链接 先说一下什么是约瑟夫环,转自:传送门 关于约瑟夫环问题,无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大( ...

  2. 51nod 1073约瑟夫环

    思路传送门 :http://blog.csdn.net/kk303/article/details/9629329 n里面挑选m个 可以递推从n-1里面挑m个 然后n-1里面的x 可以转换成 n里面的 ...

  3. 51 Nod 1073 约瑟夫环

    1073 约瑟夫环  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人 ...

  4. Java实现约瑟夫环

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

  5. poj 3517 约瑟夫环

    最简单的约瑟夫环,虽然感觉永远不会考约瑟夫环,但数学正好刷到这部分,跳过去的话很难过 直接粘别人分析了 约瑟夫问题: 用数学方法解的时候需要注意应当从0开始编号,因为取余会等到0解. 实质是一个递推, ...

  6. C++ 约瑟夫环

    约瑟夫环: 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周 ...

  7. 用pl/sql游标实现约瑟夫环

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

  8. 通过例子进阶学习C++(七)CMake项目通过模板库实现约瑟夫环

    本文是通过例子学习C++的第七篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 回顾一下约瑟夫环问题:n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然 ...

  9. php解决约瑟夫环

    今天偶遇一道算法题 "约瑟夫环"是一个数学的应用问题:一群猴子排成一圈,按1,2,-,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数, 再数到第m只,在把 ...

随机推荐

  1. TeamViewer & remote control

    TeamViewer remote control https://www.teamviewer.com/en/download/windows/ https://dl.tvcdn.de/downlo ...

  2. [luoguP1021] 邮票面值设计(DFS + dp)

    传送门 数据很小,可以DFS,判断的时候用背包DP 然而不知到枚举到哪里.... 首先枚举前可以求一遍题目中的MAX,下一层DFS的时候可以只枚举到MAX + 1,因为再往上就必定会出现断层 蒟蒻很菜 ...

  3. Python模块:time、datetime、random、os、sys、optparse

    time模块的方法: 时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. struct_time时间元组,共有九个元素组.如下图: time.localtime([secs]): ...

  4. 1 problem was encountered while building the effective model [FATAL] Non-parseable POM F:\MavenRepository\org\apache\maven\plugins\maven-resources-plugin\2.6\maven-resources-plugin-2.6.pom: start tag

    Multiple annotations found at this line: - No plugin found for prefix 'war' in the current project a ...

  5. css3 模拟标牌震荡效果

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  6. 当遇到Mac的Excel或者Word老是重复崩溃的时候

    打开Number,新建文件然后导出为Excel.之后再用Excel打开,一切都OK了.

  7. 关于C/S架构系统的安全监测

    由于工作需求,需要对一大批C/S架构的系统进行测试,所以这几天一直在摸索怎么个套路法,踩过的坑就不发了,直接奔我个人的套路: C/S架构的系统,说最直白一点就是一堆.exe的系统,他们大部分没有web ...

  8. myloader恢复mysql数据库演示样例

     mydumper是针对mysql数据库备份的一个轻量级第三方的开源工具.备份方式为逻辑备份.它支持多线程.备份速度远高于原生态的mysqldump以及众多优异特性.与其相配套的恢复工具则是mylo ...

  9. div拖拽缩放jquery插件编写——带8个控制点

    项目中需要对div进行拖拽缩放,需要有控制面板8个控制点的那种,原以为这么常见的效果应该能搜索到很多相关插件,然而可以完成拖拽的实繁,却找不到我想要的,还是自己动手丰衣足食吧 效果预览(只支持pc端) ...

  10. 三元表达式之理解/jquery源代码分析之$.inArray实现

    每次看到三元表达式就会惶惶然分不清怎样读,正如语文中的断句一样,jquery源代码中的三元表达式更是不知怎样断句. 附jquery中的inArray实现. 大家熟悉jquery的应该都不陌生inArr ...