题目描述:
N个人(编号1-N),站成一排,进行报数游戏。报数过程可能进行很多轮,有如下规则: (1) 如果剩余人数不超过3个人,则游戏结束。 (2) 大家报数,然后留下报奇数的人继续游戏,或者留下报偶数的人继续游戏。 重复如此(1)(2)两步骤,到游戏结束。 问:最终剩下的三人组有多少种情况?(注意是三人组,例如如果最后剩下2个或者1个人,不计入结果中)。 输入n, (0<n<=10000000) 输出最终结果。
分析:这道题目相对报数(一)相对容易,因为这题目不存在一个循环报数问题,所以,这个题目就变得非常容易了。但是,当我们看到题目0<n<=10000000的时候,你也许觉得这道题实现的算法的时间复杂度只可能是O(n),如果再大一点必定超时,那么什么方法才可以使得时间复杂度那么小呢?毫无疑问,肯定是找公式。经过数学归纳法之后,证明和推理过程就不说了,那我给出最后的公式吧,公式如下:
- 如果n为奇数,递推式为:f(n)=f(n/2)+f((n+1)/2);
- 如果n为偶数,递推式为:f(n)=2f(n/2);
由上面的递推式我们可以知道,假如已经给出一个数n,那么我们可以求出前n项的结果,最后n就可以求出来了。这里给出的是递推式,但是我们不需要用递归去解决,因为递归的时间复杂度为O(n2)。所以,我们用一个数组把结果保存就可以了。
算法实现:
#include<stdio.h>
#include<malloc.h>
#include<string.h>

该博客介绍了当N个人进行报数游戏,遵循特定规则直至剩下三人时,求解可能的三人组情况数的问题。博主分析了题目特点,指出当N值较大时,需要寻找低时间复杂度的解题方法。通过数学归纳法得出递推公式,并提供非递归的算法实现,以避免O(n^2)的时间复杂度。
最低0.47元/天 解锁文章
1017

被折叠的 条评论
为什么被折叠?



