LA 3882 - And Then There Was One(约瑟夫 递归)
题目大意:
N个数排成一圈,第一次删除m,以后每k个数删除一次,求最后一被删除的数。
如果这题用链表或者数组模拟整个过程的话,时间复杂度都将高达O(nk),而n<=10000,k<=10000 目测会直接TLE。
那么有没有其他的方法呢?答案是有的。
我们先忽略掉m, 分析一下每k个数删除一次,那就是经典的约瑟夫问题了。
那么,将每个数(1~n)按顺序编号为0~n-1
设第一个删除的数的编号为x,则x= k %n-1 (注意是编号,真正删除的数为编号+1)
那么剩下的n-1个数可以组成一个新的约瑟夫环。
现在的编号是什么呢?显然:(令x+1=y ,就是说y= k%n)
y , y+1 , y+2 ... n-1 , 0 , 1 ... y-2
把y放在第一个的目的是下一次从它开始数数。
重新开始数k个数.
你说重新?嗯。那么就可以这样重新编号:
y -> 0
y+1 ->1
y+2 ->2
...
...
y-2 -> n-2
现在就变成了n-1个数(编号从0~n-2)的约瑟夫问题了!
假设z是最后n-1个数留下的编号,那么z’是n个人留下的编号,则显然z’=(z+y)% n
如何知道n-1个的解?往下递归就好了嘛,知道n-2即可
所以,有:
ans [1]=0;
ans [n] =(ans[n-1]+k) %n;
(可能有人要问了:上面不是z’=(z+y)% n吗?现在怎么变成 k了?因为y= k%n,模运算)
然后,答案要+1 (编号->数)
那么这一题第一次是m怎么办呢?
也很简单,我们每次都移动K ,有n个数,那么答案就是ans[n]
但是第一次移动的是m,所以后面的移动都有个恒定的差距(k-m)
所以答案为:(ans[n] – (k – m) )% n (注意可能小于0 ,还有最终答案+1)
代码如下:
// LA 3882 - And Then There Was One
// By hr_whisper
#include<cstdio>
const int MAXN=10000+10;
int ans[MAXN];
int main()
{
int n,k,m;
while(scanf("%d%d%d",&n,&k,&m),n||k||m)
{
ans[1]=0;
for(int i=2;i<=n;i++)
ans[i]=(ans[i-1] + k ) % i;
ans[n]=( ans[n] -( k-m ) )% n;
printf("%d\n", ans[n]<0?ans[n] + n +1: ans[n]+1);
}
return 0;
}
LA 3882 - And Then There Was One(约瑟夫 递归)的更多相关文章
- LA 3882 And Then There Was One[约瑟夫问题的变形]
And Then There Was One UVALive - 3882 Sample Input Sample Output //设f[i]为(原约瑟夫问题)第i次要删除的标号 #includ ...
- LA 3882 经典约瑟夫环问题的数学递推解法
就是经典约瑟夫环问题的裸题 我一开始一直没理解这个递推是怎么来的,后来终于理解了 假设问题是从n个人编号分别为0...n-1,取第k个, 则第k个人编号为k-1的淘汰,剩下的编号为 0,1,2,3. ...
- LA 3882 And Then There Was One
解题思路:分析要好久,懒得分析了,贴了某大牛的的分析,代码就是我自己写的. N个数排成一圈,第一次删除m,以后每k个数删除一次,求最后一被删除的数. 如果这题用链表或者数组模拟整个过程的话,时间复杂度 ...
- LA 3882
动态规划: 白书上的题,看了好久看不懂刘汝佳的解法: 在网上无意中看到了大神的思路,比较好理解,膜拜! 他的思路是这样的: 设d[i]是n个数按顺时针方向分别从0开始编号,第一次删除0,以后每k个数删 ...
- UVa LA 3882 - And Then There Was One 递推,动态规划 难度: 2
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- (PAT)L2-006 树的遍历 (二叉树构建)
题目链接:https://www.patest.cn/contests/gplt/L2-006 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格 ...
- UVALive 3882 - And Then There Was One【约瑟夫问题】
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There W ...
- 约瑟夫问题(java实现)
方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] a ...
随机推荐
- HDU1796 How many integers can you find【容斥定理】
题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=1796 题目大意: 给你一个整数N.和M个整数的集合{A1.A2.-.Am}.集合内元素为非负数(包 ...
- 为root账户更名
为root账户更名 处于安全考虑许多管理员想把root更名,具体方法如下: 1.先以root登陆系统 2.用vi 编辑/etc/passwd文件,将第一行的第一个root修改为你想要的账户名,然后保存 ...
- ArraySegment 的使用 【转载】
本文转载自 http://www.cnblogs.com/overred/archive/2009/01/17/1359126.html ArraySegment顾名思义就是Array区块,数组的小抽 ...
- init进程
2.Linux下的三个特殊进程 Linux下有三个特殊的进程idle进程(PID=0),init进程(PID=1),和kthreadd(PID=2)idle进程由系统自动创建,运行在内核态idle进程 ...
- exit---退出目前的shell
exit命令 exit命令同于退出shell,并返回给定值.在shell脚本中可以终止当前脚本执行.执行exit可使shell以指定的状态值退出.若不设置状态值参数,则shell以预设值退出.状态 ...
- HDU 3487(Play with Chain-Splay)[template:Splay]
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDOJ 5357 Easy Sequence DP
a[i] 表示以i字符开头的合法序列有多少个 b[i] 表示以i字符结尾的合法序列有多少个 up表示上一层的'('的相应位置 mt[i] i匹配的相应位置 c[i] 包括i字符的合法序列个数 c[i ...
- [BZOJ1672][Usaco2005 Dec]Cleaning Shifts 清理牛棚 线段树优化DP
链接 题意:给你一些区间,每个区间都有一个花费,求覆盖区间 \([S,T]\) 的最小花费 题解 先将区间排序 设 \(f[i]\) 表示决策到第 \(i\) 个区间,覆盖满 \(S\dots R[i ...
- [51Nod]NOIP2018提高组省一冲奖班模测训练(二)
http://www.51nod.com/contest/problemList.html#!contestId=73&randomCode=4408520896354389006 还是原题大 ...
- node.js是什么
node.js是什么 一.总结 一句话总结:Node.js 就是运行在服务端的 JavaScript. 二.node.js是什么 简单的说 Node.js 就是运行在服务端的 JavaScript. ...