当前位置:编程学习 > JAVA >>

HDU1568


[java] 
package D0720; 
 
/*
 * 思路:要求斐波拉契数列的第n向的前4位数,如果直接按递推公式算肯定超时了
 * 通项公式:f(n) = (1/sqrt(5)){[(1+sqrt(5))/2]^n-[(1-sqrt(5))/2]^n}
 * 由于斐波拉契数列的第20项刚好是4位数,所以前20项可以单独用递推公式计算
 * 后面的项可以这样考虑
 * 两边取对数
 * log10(f(n))=log10(1/sqrt(5))+log10([(1+sqrt(5))/2]^n-[(1-sqrt(5))/2]^n)
 * 由于[(1-sqrt(5))/2]^n在n》=20时可以忽略不计,所以
 * log10(f(n))=log10(1/sqrt(5))+n*log10([(1+sqrt(5))/2])
 * f(n)=10^(log10(1/sqrt(5))+n*log10([(1+sqrt(5))/2]))
 * 由于10的任何次幂都是10的倍数
 * 所以f(n)的前4位值只与10^(log10(1/sqrt(5))+n*log10([(1+sqrt(5))/2]))的小数部分有关
 * 所以就。。。。开始写代码吧
 * 
 * */ 
 
import java.io.*; 
 
public class HDU1568 { 
 
    public static void main(String[] args) throws IOException { 
        StreamTokenizer st = new StreamTokenizer(new BufferedReader( 
                new InputStreamReader(System.in))); 
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); 
        // 前20项 
        int[] arr = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 
                610, 987, 1597, 2584, 4181, 6765 }; 
        int n; 
        while(st.nextToken()!=StreamTokenizer.TT_EOF){ 
            n = (int)st.nval;  www.zzzyk.com
            if(n<=20){System.out.println(arr[n]);continue;} 
            double m = Math.log10(1.0/Math.sqrt(5))+n*Math.log10((1+Math.sqrt(5))/2); 
            double p = m-(long)m; 
            p = Math.pow(10, p); 
            while(p<1000)p*=10; 
            out.println((int)p); 
        } 
        out.flush(); 
    } 
 

 

作者:lhfight
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,