目录
- 终于结束的起点
- 题目背景
- 题目描述
- 输入格式
- 输出格式
- 样例 #1
- 样例输入 #1
- 样例输出 #1
- 样例 #2
- 样例输入 #2
- 样例输出 #2
- 提示
- 样例 1 解释
- 数据范围
- 提示
- 解题思路
- Code
- 运行结果
终于结束的起点
题目背景
终于结束的起点
终于写下句点
终于我们告别
终于我们又回到原点
……
一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演。
如果这次 NOIp 是你的起点,那么祝你的 OI 生涯如同夏花般绚烂。
如果这次 NOIp 是你的终点,那么祝你的 OI 回忆宛若繁星般璀璨。
也许这是你最后一次在洛谷上打比赛,也许不是。
不过,无论如何,祝你在一周后的比赛里,好运。
当然,这道题也和轮回有关系。
题目描述
广为人知的斐波拉契数列 f i b ( n ) \mathrm{fib}(n) fib(n) 是这么计算的
f i b ( n ) = { 0 , n = 0 1 , n = 1 f i b ( n − 1 ) + f i b ( n − 2 ) , n > 1 \mathrm{fib}(n)=\begin{cases} 0,& n=0 \\ 1,& n=1 \\ \mathrm{fib}(n-1) + \mathrm{fib}(n-2),& n>1 \end{cases} fib(n)=⎩ ⎨ ⎧0,1,fib(n−1)+fib(n−2),n=0n=1n>1
也就是 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
2
样例输出 #1
3
样例 #2
样例输入 #2
6
样例输出 #2
24
提示
样例 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 ( n ) m o d 2 = 0 , f ( n + 1 ) m o d 2 = 1 f(n) \bmod 2= 0, f(n + 1) \bmod 2 = 1 f(n)mod2=0,f(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 = 0xAC666 2 \leq M \leq 706150=\verb!0xAC666! 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
来进行模运算。
解题思路
- 首先写出斐波那契数列,然后根据题意进行判断,最终得出结果。
Code
#include<iostream>
#include<vector>using namespace std;int n;
vector<int> nums(5);int main() {cin >> n;nums[0] = 0;nums[1] = 1;for (int i = 1;; i++) {int tmp = nums[0];nums[0] = nums[1];nums[1] = (tmp + nums[1]) % n;if (nums[0] % n == 0 && nums[1] % n == 1) {cout << i;break;}}return 0;
}