20141001 【 高精度?/数论--斐波那契数列 】 hdoj 1568 Fibonacci

17 篇文章 0 订阅
4 篇文章 0 订阅


F.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical Charts
Problem Archive
Realtime Judge Status
Authors Ranklist
 
      C/C++/Java Exams     
ACM Steps
Go to Job
Contest LiveCast
ICPC@China
Best Coder beta
VIP | STD Contests
Virtual Contests 
    DIY | Web-DIY beta
Recent Contests
BestCoder官方群:385386683 欢迎加入~
寻人启事:2014级新生看过来!

Fibonacci

Time 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
      
      
0 1 2 3 4 5 35 36 37 38 39 40
 

Sample Output
      
      
0 1 1 2 3 5 9227 1493 2415 3908 6324 1023
 

Author
daringQQ
 

Source
 

Recommend
8600   |   We have carefully selected several similar problems for you:   1060  1286  1788  1787  1047 
 

Statistic |  Submit |  Discuss |  Note
Hangzhou Dianzi University Online Judge 3.0
Copyright © 2005-2014 HDU ACM Team. All Rights Reserved.
Designer & Developer Wang Rongtao LinLe GaoJie GanLu
Total 0.005861(s) query 5, Server time : 2014-10-01 16:21:29, Gzip disabled






这题大数?

那好吧,上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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值