2018沈阳k(经典的约瑟夫环)
地址
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<=km<=km<=k),直接递推即可。
下面考虑m>km>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>=a+xans+x*k > =a+xans+x∗k>=a+x,即x>=a−ansk−1x>=\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(经典的约瑟夫环)相关推荐
- C语言解决经典问题约瑟夫环--数组
什么时约瑟夫环问题? 约瑟夫问题,是一个计算机科学和数学中的问题,在计算机编程的算法中,类似问题又称为约瑟夫环,又称"丢手绢问题". 问题的大致内容就是:一共有N个人,从1开始报数 ...
- 【算法经典】 约瑟夫环问题
[前言]本文讨论经典算法问题约瑟夫环问题的递归解法. 一.问题描述 作为算法中的经典问题,约瑟夫环问题自诞生以来有各种各样的变种描述,丢手绢.游戏获胜者.圆圈中最后剩下的数字.点名游戏等等,但都是同样 ...
- 单链表实现约瑟夫环问题
经典的约瑟夫环问题,用单链表实现竟然这么简单!? 目录 前言 问题 思路 代码 前言 这两天想到了之前自己用数组实现约瑟夫环问题时写了好多的代码,然后想到数据结构中的但链表好像也可以实现,于是去实践了 ...
- 猫抓老鼠c语言程序,猫抓老鼠问题C++实现一例(约瑟夫环问题)
今天偶然在网上看到了猫抓老鼠问题, 当时也没多想,只觉得网上给出的程序的确有很多需要改进的地方, 就闷头闷脑的用 循环链表 和 递归 写了一个算法实现,后来发现 这个问题实际上是经典的约瑟夫环问题的变 ...
- C语言用数组1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈;下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序。 考虑问实现约瑟夫环问题
1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈:下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序. 考虑问题: 报到T的人出圈,怎么表示出 ...
- 【循环链表】约瑟夫环问题——Python
背景:故事源自著名犹太历史学家Josephus,在罗马人占领乔塔帕特后,39个犹太人与Josephus以及他的朋友躲进了一个山洞中,39个犹太人决定宁死不屈,于是决定了一个自杀方式,41个人排成一个圈 ...
- 算法-约瑟夫环问题——python实现
Hello NanFeng 遇到了一个有点意思的题: 一艘船上有30个人,现在因为超载需要15人下船,决策者采用了一种很特殊的抽签方式 1.先让人们排成一列,按照顺序给每个人编号 2.依次从1开始报数 ...
- K - Let the Flames Begin Gym - 101955K(约瑟夫环/2018icpc沈阳)
VJ地址 思路:因为m和k的最小值一定小于2E6,那么我们可以分情况来求,如果m比较小直接o(m) 递推求出第m个死的人,如果k比较小,我们在每一轮+k的时候取模的操作都是无效的,我们可以用乘法累积起 ...
- 【图解经典算法题】如何用一行代码解决约瑟夫环问题
约瑟夫环问题算是很经典的题了,估计大家都听说过,然后我就在一次笔试中遇到了,下面我就用 3 种方法来详细讲解一下这道题,最后一种方法学了之后保证让你可以让你装逼. 问题描述:编号为 1-N 的 N 个 ...
最新文章
- Python 为了提升性能,竟运用了共享经济
- Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法
- sql查看表的数据大小_查看Oracle 数据库的每天归档量及数据库大小
- 【leetcode】Min Stack -- python版
- 从Python调用C / C ++?
- kafka中的数据发送保障
- 001 Python中的变量和字符串
- 三级等级保护之安全运维管理
- JEECG Framework 3.3.1 beta版本发布第一天战报(文档下载量破1300、代码下载量破700)...
- 能上天的代码? NASA 火星无人机飞行控制系统开源了
- node+express 使用multer进行文件上传,并且以PM2启动时的错误
- Android+SpringBoot+Vue实现安装包前台上传,后台管理,移动端检测自动更新
- 控制JetsonNano风扇命令
- 预应力锚具的分类和使用领域
- 基于51单片机的自动浇花系统
- oracle 10g ora12560,OracleORA-12560解决方法
- 第三讲使用VPB切割和加载
- 零基础HTML入门教程(11)--初识VSCode
- 一、fopen与fclose
- 标星 3.6k+ 让你无所不能的工具
热门文章
- Linux ln -s目录,Linux ln 命令的使用
- worldmap matlab,[转载]转:matlab画地图的工具:worldmap和m_map
- HTML点击图片实现提交或跳转链接页面
- 第四课:股票,多数人的找死,少数人的等死
- 那些年这么火的MyCat你还不知道吗?
- 毕业论文关键字HTML5,毕业论文关键词的选择
- MATLAB技术沙龙之如何批量处理图像的大小
- 漫谈 MQ:要消息队列(MQ)有什么用?
- leetcode 605 种花问题 (c++和python)
- android自定义相机拍照