zoukankan      html  css  js  c++  java
  • Hat's Fibonacci(大数加法+直接暴力)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1250

    hdu1250:

    Hat's Fibonacci

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 9442    Accepted Submission(s): 3096


    Problem Description
    A Fibonacci sequence is calculated by adding the previous two members the sequence, with the first two members being both 1.
    F(1) = 1, F(2) = 1, F(3) = 1,F(4) = 1, F(n>4) = F(n - 1) + F(n-2) + F(n-3) + F(n-4)
    Your task is to take a number as input, and print that Fibonacci number.
     
    Input
    Each line will contain an integers. Process to end of file.
     
    Output
    For each case, output the result in a line.
     
    Sample Input
    100
     
    Sample Output
    4203968145672990846840663646 Note: No generated Fibonacci number in excess of 2005 digits will be in the test data, ie. F(20) = 66526 has 5 digits.
     
    Author
    戴帽子的
     

     题解,同一般的斐波那契数列来说,最先的我想到了用大数加法和快速幂矩阵的方法来做,但是由于大数乘法的模板是O(n^2)所以超时了,所以考虑只用大数加法的直接暴力方法,由于斐波那契数列增长很快,所以位数不超过2005的前提下最多n 不超过10000,然后就过了,希望看到的大神吗也可以帮我提供一个复杂度小的大数乘法的模板,万分感激 

    下面给出ac代码,和用矩阵快速幂tle的代码:

    ac代码:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 string add(string s1,string s2)      
     8 {
     9       string ans = "";
    10       int i,j,x,y,k=0;
    11       for(i=s1.length()-1,j=s2.length()-1;i>=0 && j>=0 ;i--,j--)
    12       {
    13          x = s1[i] - '0';
    14          y = s2[j] - '0';
    15          ans += char((x+y+k)%10 + '0');
    16          k = (x+y+k)/10;
    17       }
    18       while(i>=0)
    19       {
    20          x=s1[i]-'0';
    21          ans += char ((x+k)%10 + '0');
    22          k = (x+k)/10;
    23          i--;
    24       }
    25       while(j>=0)
    26       {
    27          y=s2[j]-'0';
    28          ans += char((y+k)%10 + '0');
    29          k = (y+k)/10;
    30          j--;
    31       }
    32       if(k>0)
    33       ans += '1';
    34       //ans.reverse();
    35       reverse(ans.begin(),ans.end());
    36       return ans;
    37 }
    38 string ms1, ms2, ms3, ms4, ms;
    39 int main()
    40 {
    41     int n;
    42     while(~scanf("%d",&n))
    43     {
    44         ms1 = ms2 = ms3 = ms4 = "1";
    45         if(n <= 4) {puts("1"); continue;}
    46         for(int i = 0; i < n-4; i++)
    47         {
    48             ms = add(ms1, ms2);
    49             ms = add(ms, ms3);
    50             ms = add(ms, ms4);
    51             ms1 = ms2;
    52             ms2 = ms3;
    53             ms3 = ms4;
    54              ms4 = ms;
    55         }
    56         cout << ms << endl;
    57   }
    58      return 0;
    59 }

    矩阵快速幂tle代码:

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<string>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 string add(string s1,string s2)      
      8 {
      9       string ans = "";
     10       int i,j,x,y,k=0;
     11       for(i=s1.length()-1,j=s2.length()-1;i>=0 && j>=0 ;i--,j--)
     12       {
     13          x = s1[i] - '0';
     14          y = s2[j] - '0';
     15          ans += char((x+y+k)%10 + '0');
     16          k = (x+y+k)/10;
     17       }
     18       while(i>=0)
     19       {
     20          x=s1[i]-'0';
     21          ans += char ((x+k)%10 + '0');
     22          k = (x+k)/10;
     23          i--;
     24       }
     25       while(j>=0)
     26       {
     27          y=s2[j]-'0';
     28          ans += char((y+k)%10 + '0');
     29          k = (y+k)/10;
     30          j--;
     31       }
     32       if(k>0)
     33       ans += '1';
     34       //ans.reverse();
     35       reverse(ans.begin(),ans.end());
     36       return ans;
     37 }
     38 string mul(string s1,string s2)
     39 {   
     40     string ans = "";
     41     int c = 0;
     42     for(int i = s1.length()-1; i >= 0; i--)
     43     {
     44         //计算s1[i]*s2,结果保存在tem中 
     45         string tem = "";
     46         int x = s1[i] - '0',k = 0;//乘数和初始余数 
     47         for(int j = s2.length()-1; j >= 0; j--)
     48         {
     49             int y = s2[j] - '0';
     50             int d = x*y+k; 
     51             tem = char(d%10 + '0') + tem;
     52             k = d/10;
     53         }
     54         if(k)
     55         tem = char(k+'0') + tem;
     56         for(int h = 0; h < c; h++)
     57            tem = tem+'0';
     58         c++;
     59         //tem计算完毕 
     60         ans = add(ans,tem);
     61     }
     62     return ans;
     63 }
     64 struct mlt{
     65     string a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
     66     void out (){
     67         printf("%s %s %s %s
    ", a1.c_str(), a2.c_str(), a3.c_str(), a4.c_str());
     68         printf("%s %s %s %s
    ", b1.c_str(), b2.c_str(), b3.c_str(), b4.c_str());
     69         printf("%s %s %s %s
    ", c1.c_str(), c2.c_str(), c3.c_str(), c4.c_str());
     70         printf("%s %s %s %s
    ", d1.c_str(), d2.c_str(), d3.c_str(), d4.c_str());
     71     }
     72     mlt operator * (const mlt m) const
     73     {
     74         mlt tm;
     75         tm.a1 = add(add(add(mul(a1,m.a1),mul(a2,m.b1)),mul(a3,m.c1)),mul(a4,m.d1));    
     76         tm.a2 = add(add(add(mul(a1,m.a2),mul(a2,m.b2)),mul(a3,m.c2)),mul(a4,m.d2));
     77         tm.a3 = add(add(add(mul(a1,m.a3),mul(a2,m.b3)),mul(a3,m.c3)),mul(a4,m.d3));
     78         tm.a4 = add(add(add(mul(a1,m.a4),mul(a2,m.b4)),mul(a3,m.c4)),mul(a4,m.d4));
     79         tm.b1 = add(add(add(mul(b1,m.a1),mul(b2,m.b1)),mul(b3,m.c1)),mul(b4,m.d1));    
     80         tm.b2 = add(add(add(mul(b1,m.a2),mul(b2,m.b2)),mul(b3,m.c2)),mul(b4,m.d2));
     81         tm.b3 = add(add(add(mul(b1,m.a3),mul(b2,m.b3)),mul(b3,m.c3)),mul(b4,m.d3));
     82         tm.b4 = add(add(add(mul(b1,m.a4),mul(b2,m.b4)),mul(b3,m.c4)),mul(b4,m.d4));
     83         tm.c1 = add(add(add(mul(c1,m.a1),mul(c2,m.b1)),mul(c3,m.c1)),mul(c4,m.d1));    
     84         tm.c2 = add(add(add(mul(c1,m.a2),mul(c2,m.b2)),mul(c3,m.c2)),mul(c4,m.d2));
     85         tm.c3 = add(add(add(mul(c1,m.a3),mul(c2,m.b3)),mul(c3,m.c3)),mul(c4,m.d3));
     86         tm.c4 = add(add(add(mul(c1,m.a4),mul(c2,m.b4)),mul(c3,m.c4)),mul(c4,m.d4));
     87         tm.d1 = add(add(add(mul(d1,m.a1),mul(d2,m.b1)),mul(d3,m.c1)),mul(d4,m.d1));    
     88         tm.d2 = add(add(add(mul(d1,m.a2),mul(d2,m.b2)),mul(d3,m.c2)),mul(d4,m.d2));
     89         tm.d3 = add(add(add(mul(d1,m.a3),mul(d2,m.b3)),mul(d3,m.c3)),mul(d4,m.d3));
     90         tm.d4 = add(add(add(mul(d1,m.a4),mul(d2,m.b4)),mul(d3,m.c4)),mul(d4,m.d4));    
     91     return tm;
     92     }
     93 };
     94 string qkmul(int n)
     95 {
     96     mlt flag;
     97     flag.a1 = flag.a2 = flag.a3 = flag.a4 = flag.b1 = flag.c2 = flag.d3 ="1";
     98     flag.b2 = flag.b3 = flag.b4 = flag.c1 = flag.c3 = flag.c4 = flag.d1 = flag.d2 = flag.d4 = "0" ;
     99     n = n-4;
    100     mlt ret; ret.a1 = ret.b2 = ret.c3 = ret.d4 = "1";
    101     ret.a2 = ret.a3 = ret.a4 = ret.b1 = ret.b3 = ret.b4 = ret.c1 = ret.c2 = ret.c4 = ret.d1 = ret.d2 = ret.d3 = "0";
    102     while(n!=0)
    103     {
    104         if(n%2==1)
    105             ret = ret*flag;
    106         n/=2;
    107         flag = flag*flag;
    108     }
    109     //flag.out();
    110     flag = ret;
    111     string ss = "";
    112     ss = add(add(add(flag.a1,flag.a2),flag.a3),flag.a4);
    113     return ss;
    114 }
    115 
    116 int main()
    117 {
    118     int n;
    119     while(~scanf("%d",&n))
    120     {
    121         string sss = qkmul(n);
    122         cout<<sss<<endl;
    123      }
    124      return 0;
    125 }

    注明: 一般的斐波那契在n不是很大的情况可以直接用暴力的方法就可以解决了。

     
  • 相关阅读:
    SQLServer 错误: 15404,维护计划无法执行
    Axis2 服务器端抛出ServiceClass object does not implement问题解决方法
    领域驱动设计 软件核心复杂性应对之道 读书笔记
    华为实施微服务架构的五大军规
    DDD领域驱动设计基本理论知识总结
    TransactionScope使用说明
    错误:该行已经属于另一个表
    SQL基础之 时间戳
    采用左右值编码来存储无限分级树形结构的数据库表设计
    违反并发性: UpdateCommand影响了预期 1 条记录中的 0 条 解决办法
  • 原文地址:https://www.cnblogs.com/shanyr/p/4862861.html
Copyright © 2011-2022 走看看