hdu-1568斐波那契數列通項公式的應用
阿新 • • 發佈:2018-12-22
2007年到來了。經過2006年一年的修煉,數學神童zouyu終於把0到100000000的Fibonacci數列
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部給背了下來。
接下來,CodeStar決定要考考他,於是每問他一個數字,他就要把答案說出來,不過有的數字太長了。所以規定超過4位的只要說出前4位就可以了,可是CodeStar自己又記不住。於是他決定編寫一個程式來測驗zouyu說的是否正確。
Input
輸入若干數字n(0 <= n <= 100000000),每個數字一行。讀到檔案尾。
Output
輸出f[n]的前4個數字(若不足4個數字,就全部輸出)。
對於資料範圍很大,位數大於四位的在f[21]的時候就到了。題目要求前四位。說實話沒有想法,雖然知道斐波那切數列但是不知道他還有通項公式。自己比較菜;在百度上找到了這個公式:
可是如何求得前四位呢,又不會了;這裡又考察了對數的性質。
在這裡有一個證明很好的部落格https://blog.csdn.net/niushuai666/article/details/7013352
然後就是程式碼了:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<queue> #define pi acos(-1) #define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++) #define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --) #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define eps 1e-7 using namespace std; typedef long long ll; const int maxn = 1e8; const int INF = 0x3f3f3f3f; const double EPS = 1e-10; const ll mod = 1e9 + 7; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} inline int read(){ int ret=0,f=0;char ch=getchar(); while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar(); while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar(); return f?-ret:ret; } ll f[maxn]; ll n; void init(){ f[0] = 0; f[1] = 1; for(int i =2; i < 21; i ++){ f[i] = f[i-1] + f[i-2]; } return ; } int main(){ ios::sync_with_stdio(false); init(); while(cin >> n){ if(n < 21){ cout << f[n] << endl; }else{ double t = -0.5*log(5.0)/log(10.0) + ((double)n)*log((sqrt(5.0)+1.0)/2.0)/log(10.0); t -= floor(t); t = pow(10.0, t); while(t < 1000){ t *= 10; } cout << (int)t << endl; } } return 0; }
繼續加油: