【洛谷 4994】终于结束的起点

【题目】

传送门

题目背景:

终于结束的起点
终于写下句点
终于我们告别
终于我们又回到原点
… … ……

一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演。

如果这次 NOIp 是你的起点,那么祝你的 OI 生涯如同夏花般绚烂。

如果这次 NOIp 是你的终点,那么祝你的 OI 回忆宛若繁星般璀璨。

也许这是你最后一次在洛谷上打比赛,也许不是。

不过,无论如何,祝你在一周后的比赛里,好运。

当然,这道题也和轮回有关系。

题目描述:

广为人知的斐波拉契数列 f i b ( n ) \mathrm{fib}(n) fib(n) 是这么计算的
在这里插入图片描述

也就是 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ⋯ 0, 1, 1, 2, 3, 5, 8, 13 \cdots 0,1,1,2,3,5,8,13,每一项都是前两项之和。

F 发现,如果把斐波拉契数列的每一项对任意大于 1 1 1 的正整数 m m m 取模的时候,数列都会产生循环。

当然,小 F 很快就明白了,因为 ( f i b ( n − 1 )   m o d   m ) (\mathrm{fib}(n - 1) \bmod m) (fib(n1)modm) ( f i b ( n − 2 )   m o d   m ) (\mathrm{fib}(n - 2) \bmod m) (fib(n2)modm) 最多只有 m 2 m ^ 2 m2 种取值,所以在 m 2 m ^ 2 m2 次计算后一定出现过循环。

甚至更一般地,我们可以证明,无论取什么模数 m m m,最终模 m m m 下的斐波拉契数列都会是 0 , 1 , ⋯   , 0 , 1 , ⋯ 0, 1, \cdots, 0, 1, \cdots 0,1,,0,1,

现在,给你一个模数 m m m,请你求出最小的 n > 0 n > 0 n>0,使得 f i b ( n )   m o d   m = 0 , f i b ( n + 1 )   m o d   m = 1 \mathrm{fib}(n) \bmod m = 0, \mathrm{fib}(n + 1) \bmod m = 1 fib(n)modm=0,fib(n+1)modm=1

输入格式:

输入一行一个正整数 m m m

输出格式:

输出一行一个正整数 n n n

样例数据:

【样例 1 1 1

输入
2

输出
3

【样例 2 2 2

输入
6

输出
24

说明:

【样例 1 1 1 解释】

斐波拉契数列为 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , ⋯ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, \cdots 0,1,1,2,3,5,8,13,21,34,,在对 2 2 2 取模后结果为 0 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , ⋯ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, \cdots 0,1,1,0,1,1,0,1,1,0,

我们可以发现,当 n = 3 n = 3 n=3 时, f i b ( n )   m o d   2 = 0 , f i b ( n + 1 )   m o d   2 = 1 \mathrm{fib}(n) \bmod 2= 0, \mathrm{fib}(n + 1) \bmod 2 = 1 fib(n)mod2=0,fib(n+1)mod2=1,也就是我们要求的 n n n 的最小值。

【数据范围】

对于 30 % 30\% 30% 的数据, m ≤ 18 m \leq 18 m18

对于 70 % 70\% 70% 的数据, m ≤ 2018 m \leq 2018 m2018

对于 100 % 100\% 100% 的数据, 2 ≤ m ≤ 706150 = 2 \leq m \leq 706150= 2m706150= 0xAC666

提示:

如果你还不知道什么是取模 (   m o d   ) (\bmod) (mod),那我也很乐意告诉你,模运算是求整数除法得到的余数,也就是竖式除法最终「除不尽」的部分,也即
a &VeryThinSpace; m o d &VeryThinSpace; m = k &ThickSpace; ⟺ &ThickSpace; a = b m + k   ( m &gt; 0 , 0 ≤ k &lt; m ) a \bmod m =k \iff a = bm + k\ (m &gt; 0, 0 \leq k &lt; m) amodm=ka=bm+k (m>0,0k<m)

其中 a , b , k a, b, k a,b,k 都是非负整数。

如果你使用 C / C++,你可以使用 % 来进行模运算。

如果你使用 Pascal,你可以使用 mod 来进行模运算。


【分析】

这道题走心了啊

其实不是一道难题,暴力就可以过(暴力出奇迹啊

然后注意一下内存的优化(可以用滚动数组)就可以了

希望自己一个星期后的 NOIP RP++ 啊,就是暴力都能 A 的那种(当然是不可能的


【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	int m,i=1;
	scanf("%d",&m);
	int a=0,b=1,c;
	while(1)
	{
		c=(a+b)%m;
		if(b==0&&c==1)
		{
			printf("%d",i);
			return 0;
		}
		a=b,b=c,i++;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值