| ||||||||||
| ||||||||||
FibonacciTime Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3562 Accepted Submission(s): 1621
Problem Description
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个数字,就全部输出)。
Sample Input
Sample Output
Author
daringQQ
Source
Recommend
| ||||||||||
|
这题大数?
那好吧,上JAVA(矩阵快速幂)。。。
结果TLE超时了。【下面的是失败的模板】
好吧,C++大数模板?
。。。。。。
其实这题应该是数论!!
重点在:要求保留前4位。
当n较大时,斐波那契数列逼近于:
其中:
于是:
这就是正解了。。。
import java.io.*;
import java.math.*;
import java.util.*;
public class Main{
public static void main(String[]args) throws Exception{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
//Scanner sc = new Scanner(System.in);
BigInteger ans;
String ss;
while( true ){
ss = in.readLine();
if( ss==null ) break;
int n = Integer.parseInt( ss );
if( n==0 ) out.write( "0" );
else if( n==1 ) out.write( "1" );
else{
mat d = new mat(1,1,1,0);
mat e = new mat();
e = e.pow(d, n-1);
ans = e.m[0][0];
String s = ans.toString();
if( s.length()<=4 ) out.write( s );
else out.write( s.substring(0, 4) );
}
out.newLine();
out.flush();
}
}
}
class mat{
public BigInteger[][] m;
public mat(){
m = new BigInteger[2][2];
}
public mat(int a, int aa, int b, int bb){
m = new BigInteger[2][2];
m[0][0] = BigInteger.valueOf(a);
m[0][1] = BigInteger.valueOf(aa);
m[1][0] = BigInteger.valueOf(b);
m[1][1] = BigInteger.valueOf(bb);
}
public mat mul(mat a, mat b){
mat d = new mat(0,0,0,0);
for(int i=0; i<=1; i++)
for(int j=0; j<=1; j++)
for(int k=0; k<=1; k++)
d.m[i][j] = d.m[i][j].add( a.m[i][k].multiply(b.m[k][j]) );
return d;
}
public mat pow(mat a, int n){
mat d = new mat(1,0,0,1);
while( n>0 ){
if( n%2==1 ) d = mul(d, a);
a = mul(a, a);
n /= 2;
}
return d;
}
}
#include <math.h>
#include <string.h>
#include <stdio.h>
using namespace std;
const int NN = 10000;
const double gold = (1.0+sqrt(5.0))/2.0;
int f[1010]={0, 1}, len=2;
int n;
int main(){
do{
f[len] = f[len-1] + f[len-2];
}while( !(f[len++]/NN) );
len--;
while( EOF != scanf("%d", &n) ){
if( n<len ){
printf("%d\n", f[n]);
continue;
}
double AB = n*log(gold)/log(10)-log(sqrt(5))/log(10);
double B = AB-floor(AB);
int ans = (int)(1000*pow(10,B));
printf("%d\n", ans);
}
return 0;
}