zoukankan      html  css  js  c++  java
  • 2008 Round 1A C Numbers (矩阵快速幂)

    题目描述:

    请输出(3+√5)^n整数部分最后3位。如果结果不超过2位,请补足前导0.

    分析:

    我们最容易想到的方法肯定是直接计算这个表达式的值,但是这样的精度是不够的。朴素的算法没有办法得到答案。但是我们根据分析可以发现这个问题不用求出√5的值也可以得到答案。

    我们可以发现,将(3+√5)^n这个式子展开后就是An+Bn√5的形式。同样的,我们将(3-√5)^n这个式子展开后就是An-Bn√5。

    因此,(3+√5)^n+(3-√5)^n=2An是一个整数,其中0<(3-√5)^n <1,是解题的关键。由于(3+√5)^n=2An-(3-√5)^n,所以(3+√5)^n的整数部分就是2An-1.

    根据上面的推导,只要高效的求出An就可以解决这个问题了。由于(3+√5)^(n+1)=(3+√5)(3+√5)^n=(3+√5) (An+Bn√5),我们可以得到An,Bn,A(n+1),B(n+1)的递推关系。

    A(n+1)=3An+5Bn;

    B(n+1)=An+3Bn;

    A0=1 B0=0;

    我们可以用矩阵表示这个递推关系,因此可以使用快速幂运算。因为结果要求的是后三位,所以最后取余1000就行。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    struct Node
    {
        int e[2][2];
        Node()
        {
            memset(e,0,sizeof(e));
        }
    };
    Node mul(Node a,Node b)
    {
        Node c;
    
        for(int i=0; i<2; i++)
            for(int j=0; j<2; j++)
                for(int k=0; k<2; k++)
                {
                    c.e[i][j]+=(a.e[i][k]*b.e[k][j]);
                }
        return c;
    }
    
    Node quick_mi(Node a,int b)
    {
        Node c;
        c.e[0][0]=1;
        c.e[1][1]=1;
        while(b)
        {
            if(b&1)
                c=mul(c,a);
            b>>=1;
            a=mul(a,a);
        }
        return c;
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            Node A;
            A.e[0][0]=3;
            A.e[0][1]=5;
            A.e[1][0]=1;
            A.e[1][1]=3;
            A=quick_mi(A,n);
            printf("%03d
    ",(2*A.e[0][0]-1)%1000);
        }
        return 0;
    }
    
  • 相关阅读:
    文章参考
    选择标识符(identifier)
    linux常见命令2
    Django框架之MVT(1)
    Tornado入门二
    2.Flask-jinjia2模板
    JQuery扩展和事件
    JQuery文档操作
    Jquery学习
    Jquery属性操作(入门二)
  • 原文地址:https://www.cnblogs.com/cmmdc/p/7297810.html
Copyright © 2011-2022 走看看