17965 幸运之星(优先做)

时间限制:100MS  内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC;VC

Description

每年新年派对的最后一个节目就是选出下年的“幸运之星”,有丰厚的大礼包的噢~~。  O(∩_∩)O

所以每位参加派对的人士都摩拳擦掌跃跃欲试。选择的办法是这样约定的:

(1)所有参与的人员数n,让n个人一字排开,然后至左向右从1开始报数,凡报到奇数号的全部后退剔除,剩下的人员,

又至左向右报数,逢奇剔除,如此不断的递归下去,直至只有一个人为止,这个人就是“幸运之星”。

(2)所有参与的人员数n,先随机抽取一个m值(从黑暗小箱中随机摸一个,m可能比n小或相等,也可能大于n),所有

参与的人员列成环形,然后从位置1开始报数,凡报到m的倍数的人后退剔除,剩下的人员,从刚才位置继续报数,逢m的

倍数的人剔除,如此不断的递归下去,直至只有一个人为止,这个人就是“幸运之星”。 如:n=8,m=4,如下图所示,幸

运之星为6号。

现在,请你分析上面两种节目方式,若想获得幸运大礼包,应该选哪个初始编号的位置来站?

注意此题设置的时限很短,也就不建议你采用队列或循环列表去模拟这个剔除的过程而得到最后的解答。这里,我们更应

该分析一下,这个问题的递归思路。有了分析的递归公式,就可以在很短时间内完成“幸运之星”的计算。

输入格式

输入:n和m(m只和第二个问题有关,与第一个问题无关)。

n和m的范围:n,m
<1000000。

输出格式

输出:幸运之星游戏未开始剔除之前的最初的编号。(1)题和(2)题的解,中间空格相连。

输入样例

8 4

输出样例

8 6

提示

此题不要用递归来写,因为n,m <1000000,递归深度若和n有关的话,这么深的递归是无法执行的,递归栈要爆了。

因此,第(1)问和第(2)问都尽量避免用递归过程,而要想方设法推导出“递推公式”,由递推公式直接计算得到。

(1)我们把“幸运之星”的初始编号定为J(n)。我们初写如下几个J(n):

n      1   
2    3    4   
5    6   
7    8    9   
10  …

------------------------------------------------------------

J(n)   1   
2    2    4   
4    4    4   
8    8     8  …

把n分奇偶来讨论:即n=2k时的J(2k)和n=2k+1的J(2k+1)来探讨。

1)当n=2k时,所有奇数都删去,剩下的偶数 2 4 … 2k又重新形成和之前类似的一字型排开队列,

只是编号加倍。所以J(2k)=2J(k);

2)当n=2k+1时,所有的奇数都删去了,剩下的偶数和上面是相同的:2 4 … 2k,也只是编号加倍。

所以J(2k+1)=2J(k);

3)当n=1时,J(1)=1。

递归关系清晰,这个递归式是非常有效的,因为每次应用此递归式时,n都可以大致减半,大约递

归19次,就能计算到J(1 000 000)了,现在你可以编程实现了吧。

这个问题是寻找“幸运之星”编号,如果你很想中奖,那脑子就得快速计算最有利的位置,所以还希望找

出J(n)的一般闭形式,毕竟没有太多时间递归计算。把n表示成 n = 2^p + q,其中2^p是指不超过n

的2的最大幂,q是余量。递归式的闭形式解:J(n) = J(2^p + q) = 2^p    J(1)=1。

(2)这里的m指的是:逢m的倍数的人剔除。且参与人员是环形的。我们把“幸运之星”的初始编号定为J(n),

题目上的图的例子就是m=4,J(8)=6。我们需要考虑,某个人剔除前和剔除后的编号对应关系。

如题中图(n=8,m=4)为例说明:在图(a)中,第一个人n4剔除,那n5即视为1,重新开始n-1个人的幸

运之星游戏。更一般的,由于第一个人编号是从1开始而非0开始,所以第一个剔除的人编号为 (m-1)%n+1,

剩下n-1个人重新组成一个环形,只是这时候从m%n+1开始。 在 (m-1)%n+1被剔除前和剔除后,其余人的

编号形成这样的映射:

剔除前编号      剔除了(m-1)%n+1   剔除后编号

(m)%n+1               ---               1

(m+1)%n+1             ---               2

...                                ...

(m-3)%n+1             ---              n-2

(m-2)%n+1             ---              n-1

也可以反过来说,这里n-1长环的元素编号和n长环的元素编号之间的映射关系是:

Index(n)
= (Index(n-1)+m-1)%n + 1

继续下一步剔除,将变成n-2长的环,他们之间的关系则是Index(n-1) =
(Index(n-2)+m-1)%(n-1) + 1。 ……。

一直剔除下去,最后肯定是只有一个元素(这就是“幸运之星”),这个元素对应编号为1,也就是Index(1) =1。

那它的上一级环2个元素的编号是多少呢?按前面公式倒推回去,Index(2) =
(Index(1)+m-1)%2 + 1,对应3个元

素、4个元素的编号呢?一路倒推下去,就可以得到n个元素环的编号了,这个递推关系就是:

Index(n)
= (Index(n-1)+m-1)%n + 1       
Index(1)=1。

总结递归公式,我们把“幸运之星”的初始编号定为J(n),也就是上面分析的Index(n):

1)当n=1时,J(1) = 1;

2)当n>1时,J(n) = (J(n-1)+m-1)%n + 1。

作者

zhengchan

设下标的编号从1开始

对于第一问,一开始我是找规律的,感觉太渣渣了,正解真的很优美。

设F(n)表示长度为n的序列,的答案是什么。

考虑n是偶数,那么就是1、2、3、4、5、6、7、8.....2k

第一步,就抽取了成为2、4、6、8.....2k

就是长度是n/2的子问题,明显可以递归求解,但是下标不同,不过可以提取2这个公因子,所以F(n) = 2 * F(n / 2)

考虑n是奇数,1、2、3、4、5、6、7、8.....2k+1

然后最后一个奇数会剔除的,就也是变成了2、4、6、8.....2k的子问题,所以F(n) = 2 * F(n / 2)

对于第二问,

设F(n)表示长度为n的序列,每次报号是m的时候要剔除的时候的最优位置是哪一个。

然后,第一次很容易求解出来,要删除的就是 (m - 1) % n + 1 -----------下标为1的模%法

然后就变成了m%n+1对应报号1, (m+1)%n+1对应报号2, ..... (m + n - 2)%n + 1对应报号n - 1的,长度是n-1的子问题。

关键是她们的长度可以递归,但是id不同,

因为我们设了F(n)是求解长度是n的时候的最优位置,那么把右边映射回来左边也不是难事。

F(1) = 1

F(n) = (m - 1 + F(n - 1)) % n + 1

#include <cstdlib>
#include <cstdio>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
int n, m;
int dp[];
void work() {
int ans1, ans2;
scanf("%d%d", &n, &m);
for (int i = ; i >= ; --i) {
if (( << i) <= n) {
ans1 = << i;
break;
}
}
dp[] = ;
for (int i = ; i <= n; ++i) {
dp[i] = (m + dp[i - ] - ) % i + ;
// printf("%d\n", dp[i]);
}
printf("%d %d\n", ans1, dp[n]);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

17965 幸运之星(优先做) 约瑟夫环问题O(n)的更多相关文章

  1. javascript中使用循环链表实现约瑟夫环问题

    1.问题 传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第 ...

  2. tc 147 2 PeopleCircle(再见约瑟夫环)

    SRM 147 2 600PeopleCircle Problem Statement There are numMales males and numFemales females arranged ...

  3. 【约瑟夫环变形】UVa 1394 - And Then There Was One

    首先看到这题脑子里立刻跳出链表..后来继续看如家的分析说,链表法时间复杂度为O(n*k),肯定会TLE,自己才意识到果然自个儿又头脑简单了 T^T. 看如家的分析没怎么看懂,后来发现这篇自己理解起来更 ...

  4. 简单约瑟夫环的循环单链表实现(C++)

    刚刚接触C++以及数据结构,今天做了第一次尝试用C++和数据结构解决问题,问题是基于约瑟夫环问题的简单版. 先来看看约瑟夫环问题的介绍: 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3.. ...

  5. 【剑指offer】约瑟夫环问题

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/27957407 题目描写叙述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小 ...

  6. C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解

    剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...

  7. 约瑟夫环简介,问题以及java实现

    问题:一群猴子排成一圈,按1,2,--.,n依次编号.然后从第一只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,再把它踢出去-------.,如此不停的进行下去,直到最后只剩下一只猴 ...

  8. King's Game---hdu5643(约瑟夫环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5643    约瑟夫环问题的原来描述为,设有编号为1,2,……,n的n(n>0)个人围成一个圈,从 ...

  9. 组合数学--约瑟夫环问题 Josephus

    约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有n个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过k-2个人(因为第 ...

随机推荐

  1. SDUT 2107 图的深度遍历

    图的深度遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 请定一个无向图,顶点编号从0到 ...

  2. HDU 1796 How many integers can you find (容斥)

    题意:给定一个数 n,和一个集合 m,问你小于的 n的所有正数能整除 m的任意一个的数目. 析:简单容斥,就是 1 个数的倍数 - 2个数的最小公倍数 + 3个数的最小公倍数 + ...(-1)^(n ...

  3. 使用Serializable接口进行JAVA的序列化和反序列化

    OBJECT STREAMS – SERIALIZATION AND DESERIALIZATION IN JAVA EXAMPLE USING SERIALIZABLE INTERFACE Hite ...

  4. WebGoat系列实验AJAX Security

    WebGoat系列实验AJAX Security DOM Injiction 实验对象是一个接受激活密钥后允许你访问的系统,实验目标是尝试将激活按钮变得可以点击. 直接修改页面代码激活按钮,Chrom ...

  5. WebGoat系列实验Authentication Flaws

    WebGoat系列实验Authentication Flaws Forgot Password Web应用经常给用户提供取回密码的功能,但是许多应用的实现策略实现的很差,用于验证用户的信息非常简单. ...

  6. 692. Top K Frequent Words

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  7. Redis源码阅读---连接建立

    对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供的集群功能是无中心的,命令请求可以发送到 ...

  8. JavaScript之入门篇(二)

    终于学到后面的语法部分了,感觉这门语言基础部分和当初学习VB的时候感觉一样一样的,章节目录让我不禁又想到了VB课本.由于怕学过了,过段时间忘了,于是,大概总结一下. 数据类型部分 ① Typeof操作 ...

  9. 洛谷P4462 [CQOI2018]异或序列(莫队)

    打广告->[这里](https://www.cnblogs.com/bztMinamoto/p/9538115.html) 我蠢了…… 如果$a_{l} xor ...a_{r}=k$,那么只要 ...

  10. Linux之NFS网络文件系统

    NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络资源共享.在NFS的应用中,本地NFS的客户端应用可 ...