【题目】
题目背景:
终于结束的起点
终于写下句点
终于我们告别
终于我们又回到原点
… … …… ……
一个个 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(n−1)modm) 和 ( f i b ( n − 2 )   m o d   m ) (\mathrm{fib}(n - 2) \bmod m) (fib(n−2)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 m≤18;
对于 70 % 70\% 70% 的数据, m ≤ 2018 m \leq 2018 m≤2018;
对于
100
%
100\%
100% 的数据,
2
≤
m
≤
706150
=
2 \leq m \leq 706150=
2≤m≤706150= 0xAC666
。
提示:
如果你还不知道什么是取模
(
 
m
o
d
 
)
(\bmod)
(mod),那我也很乐意告诉你,模运算是求整数除法得到的余数,也就是竖式除法最终「除不尽」的部分,也即
a
 
m
o
d
 
m
=
k
  
⟺
  
a
=
b
m
+
k
(
m
>
0
,
0
≤
k
<
m
)
a \bmod m =k \iff a = bm + k\ (m > 0, 0 \leq k < m)
amodm=k⟺a=bm+k (m>0,0≤k<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;
}