地址

K Let the Flames Begin

首先,对于经典的约瑟夫环问题,我们记f(n,m)f(n,m)f(n,m)表示初始有nnn个人,第mmm个出队的人是谁(从0号开始报数)。则有递推式f(n,m)=(f(n−1,m−1)+k)%nf(n,m)=(f(n-1,m-1)+k)\ \%\ nf(n,m)=(f(n−1,m−1)+k) % n 其中kkk表示每报数kkk次一个人出队,注意编号从0开始

递推式的证明: 考虑现在有nnn个人围成一圈,然后从0开始报数。假设第一个出队的人是xxx ,这时还有n−1n-1n−1个人,我们从刚刚出去的那个人的下一个人从0重新编号,那么以当前局面重新开始,第m−1m-1m−1个出队的人是初始所求的同一个人,但编号不同,差多少呢?即f(n,m)=(f(n−1,m−1)+k)%nf(n,m)=(f(n-1,m-1)+k)\ \%\ nf(n,m)=(f(n−1,m−1)+k) % n 。 +1 -1 细节手玩一下。

回到本题,由于m,km,km,k可能会很大,但不会同时很大,当mmm较小的时候(m&lt;=km&lt;=km<=k),直接递推即可。

下面考虑m&gt;km&gt;km>k的情况,会发现模数大部分情况下远大于kkk,也就是说可以用乘法代替多次加法,这样可以降低时间复杂度。具体代替多少次呢?考虑f(a,b)=ansf(a,b)=ansf(a,b)=ans, 假设代替xxx次,则f(a+x,b+x)=ans+x∗kf(a+x,b+x) = ans+x*kf(a+x,b+x)=ans+x∗k 进行取模的等价条件是ans+x∗k&gt;=a+xans+x*k &gt; =a+xans+x∗k>=a+x,即x&gt;=a−ansk−1x&gt;=\frac{a-ans}{k-1}x>=k−1a−ans​ 即代替次数确定了(整除不整除,快加到mmm了等细节注意一下即可)。

时间复杂度 O(感觉能过)O(感觉能过)O(感觉能过)

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;const int maxn=2e6+10;
ll m,n,k;ll f[maxn];int main()
{//freopen("in.txt","r",stdin);int t;cin>>t;int T=0;while(t--){T++;cin>>n>>m>>k;cout<<"Case #"<<T<<": ";if(m<=k){//直接递推ll tp=(n-m+1);f[1] = (k-1) % tp;  //编号从0开始for(int i=2;i<=m;++i) f[i] = (f[i-1]+k)%(++tp);cout<<f[m]+1<<endl;}else{if(k==1) cout<<m<<endl;else{ll tp = n-m+1;ll ans = (k-1) % tp;  //编号从0开始ll now = 1;while(1){if((tp-ans)%(k-1)==0){ll x = (tp-ans)/(k-1) -1 ;x = min(x,m-now);ans += x*k;now += x;tp  += x;if(now==m) break;ans =(ans + k) % (tp+1);now +=1;tp  +=1;if(now==m) break;assert(now <=m);}else{ll x = (tp-ans)/(k-1);x = min(x,m-now);ans += x*k;now += x;tp +=x;if(now==m) break;ans =(ans + k) % (tp+1);now +=1;tp  +=1;if(now==m) break;assert(now <=m);}}cout<<ans+1<<endl;}}}return 0;
}

2018沈阳k(经典的约瑟夫环)相关推荐

  1. C语言解决经典问题约瑟夫环--数组

    什么时约瑟夫环问题? 约瑟夫问题,是一个计算机科学和数学中的问题,在计算机编程的算法中,类似问题又称为约瑟夫环,又称"丢手绢问题". 问题的大致内容就是:一共有N个人,从1开始报数 ...

  2. 【算法经典】 约瑟夫环问题

    [前言]本文讨论经典算法问题约瑟夫环问题的递归解法. 一.问题描述 作为算法中的经典问题,约瑟夫环问题自诞生以来有各种各样的变种描述,丢手绢.游戏获胜者.圆圈中最后剩下的数字.点名游戏等等,但都是同样 ...

  3. 单链表实现约瑟夫环问题

    经典的约瑟夫环问题,用单链表实现竟然这么简单!? 目录 前言 问题 思路 代码 前言 这两天想到了之前自己用数组实现约瑟夫环问题时写了好多的代码,然后想到数据结构中的但链表好像也可以实现,于是去实践了 ...

  4. 猫抓老鼠c语言程序,猫抓老鼠问题C++实现一例(约瑟夫环问题)

    今天偶然在网上看到了猫抓老鼠问题, 当时也没多想,只觉得网上给出的程序的确有很多需要改进的地方, 就闷头闷脑的用 循环链表 和 递归 写了一个算法实现,后来发现 这个问题实际上是经典的约瑟夫环问题的变 ...

  5. C语言用数组1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈;下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序。 考虑问实现约瑟夫环问题

    1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈:下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序. 考虑问题: 报到T的人出圈,怎么表示出 ...

  6. 【循环链表】约瑟夫环问题——Python

    背景:故事源自著名犹太历史学家Josephus,在罗马人占领乔塔帕特后,39个犹太人与Josephus以及他的朋友躲进了一个山洞中,39个犹太人决定宁死不屈,于是决定了一个自杀方式,41个人排成一个圈 ...

  7. 算法-约瑟夫环问题——python实现

    Hello NanFeng 遇到了一个有点意思的题: 一艘船上有30个人,现在因为超载需要15人下船,决策者采用了一种很特殊的抽签方式 1.先让人们排成一列,按照顺序给每个人编号 2.依次从1开始报数 ...

  8. K - Let the Flames Begin Gym - 101955K(约瑟夫环/2018icpc沈阳)

    VJ地址 思路:因为m和k的最小值一定小于2E6,那么我们可以分情况来求,如果m比较小直接o(m) 递推求出第m个死的人,如果k比较小,我们在每一轮+k的时候取模的操作都是无效的,我们可以用乘法累积起 ...

  9. 【图解经典算法题】如何用一行代码解决约瑟夫环问题

    约瑟夫环问题算是很经典的题了,估计大家都听说过,然后我就在一次笔试中遇到了,下面我就用 3 种方法来详细讲解一下这道题,最后一种方法学了之后保证让你可以让你装逼. 问题描述:编号为 1-N 的 N 个 ...

最新文章

  1. Python 为了提升性能,竟运用了共享经济
  2. Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法
  3. sql查看表的数据大小_查看Oracle 数据库的每天归档量及数据库大小
  4. 【leetcode】Min Stack -- python版
  5. 从Python调用C / C ++?
  6. kafka中的数据发送保障
  7. 001 Python中的变量和字符串
  8. 三级等级保护之安全运维管理
  9. JEECG Framework 3.3.1 beta版本发布第一天战报(文档下载量破1300、代码下载量破700)...
  10. 能上天的代码? NASA 火星无人机飞行控制系统开源了
  11. node+express 使用multer进行文件上传,并且以PM2启动时的错误
  12. Android+SpringBoot+Vue实现安装包前台上传,后台管理,移动端检测自动更新
  13. 控制JetsonNano风扇命令
  14. 预应力锚具的分类和使用领域
  15. 基于51单片机的自动浇花系统
  16. oracle 10g ora12560,OracleORA-12560解决方法
  17. 第三讲使用VPB切割和加载
  18. 零基础HTML入门教程(11)--初识VSCode
  19. 一、fopen与fclose
  20. 标星 3.6k+ 让你无所不能的工具

热门文章

  1. Linux ln -s目录,Linux ln 命令的使用
  2. worldmap matlab,[转载]转:matlab画地图的工具:worldmap和m_map
  3. HTML点击图片实现提交或跳转链接页面
  4. 第四课:股票,多数人的找死,少数人的等死
  5. 那些年这么火的MyCat你还不知道吗?
  6. 毕业论文关键字HTML5,毕业论文关键词的选择
  7. MATLAB技术沙龙之如何批量处理图像的大小
  8. 漫谈 MQ:要消息队列(MQ)有什么用?
  9. leetcode 605 种花问题 (c++和python)
  10. android自定义相机拍照