1. 程式人生 > >洛谷P4994 終於結束的起點

洛谷P4994 終於結束的起點

題目背景

終於結束的起點
終於寫下句點
終於我們告別
終於我們又回到原點
……

一個個 OIer 的競賽生涯總是從一場 NOIp 開始,大多也在一場 NOIp 中結束,好似一次次輪迴在不斷上演。
如果這次 NOIp 是你的起點,那麼祝你的 OI 生涯如同夏花般絢爛。
如果這次 NOIp 是你的終點,那麼祝你的 OI 回憶宛若繁星般璀璨。
也許這是你最後一次在洛谷上打比賽,也許不是。
不過,無論如何,祝你在一週後的比賽裡,好運。

當然,這道題也和輪迴有關係。

題目描述

廣為人知的斐波拉契數列fib(n) 是這麼計算的

也就是 0,1,1,2,3,5,8,13⋯,每一項都是前兩項之和。

小 F 發現,如果把斐波拉契數列的每一項對任意大於 11 的正整數 MM 取模的時候,數列都會產生迴圈。

當然,小 F 很快就明白了,因為 (fib(n1)modM) 和 (fib(n2)modM) 最多隻有 M2 種取值,所以在 M2 次計算後一定出現過迴圈。

甚至更一般地,我們可以證明,無論取什麼模數 MM,最終模 MM 下的斐波拉契數列都會是 0,1,,0,1,⋯。

現在,給你一個模數 M,請你求出最小的 n>0,使得 fib(n)modM=0,fib(n+1)modM=1。

輸入輸出格式

輸入格式:

 

輸入一行一個正整數 M。

 

輸出格式:

 

輸出一行一個正整數 n。

 

輸入輸出樣例

輸入樣例#1:  複製
2
輸出樣例#1:  複製
3
輸入樣例#2:  複製
6
輸出樣例#2:  複製
24

說明

樣例 1 解釋

斐波拉契數列為 0,1,1,2,3,5,8,13,21,34,⋯,在對 22 取模後結果為 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, \cdots0,1,1,0,1,1,0,1,1,0,⋯。

我們可以發現,當 n=3 時,f(n)mod2=0,f(n+1)mod2=1,也就是我們要求的 n 的最小值。

資料範圍

對於 30% 的資料,M18;

對於 70% 的資料,M2018;

對於 100% 的資料,2M706150=0xAC666

提示

如果你還不知道什麼是取模 (mod),那我也很樂意告訴你,模運算是求整數除法得到的餘數,也就是豎式除法最終「除不盡」的部分,也即amodM=ka=bM+k (M>0,0k<M)其中 a,b,k 都是非負整數。

如果你使用 C / C++,你可以使用 % 來進行模運算。

如果你使用 Pascal,你可以使用 mod 來進行模運算。

/*
    這到底是起點還是終點呢?
    這道題很簡單,暴力就可以水過,甚至不要打表啥的
    滾動地使用a,b,c三個變數,a是第一個數,b是第二個數,c是第三個數
    其他的看程式就好 很容易理解的
*/

#include <bits/stdc++.h>

using namespace std;

int a,b,c,ans;

int main(){
    int mod;scanf("%d",&mod);
    a = 0,b = 1;
    while(true){
        ans++;
        c = (a+b)%mod;
        if(c == 1 && b == 0){
            printf("%d\n",ans);
            return 0;
        }
        a = b%mod;
        b = c%mod;
    }
    return 0;
}