HDU 1757 A Simple Math Problem 矩阵相乘

该题搞了一个晚上才A了它,刚开始一直不能出正确结果,总认为是我的二分哪里错了,修改了几个小时,还重敲了,后来才发现是矩阵建反了,该题最重要的是建立矩阵,如果矩阵建立好了,就万事顺利了,怎样建立这个矩阵了,我们来讨论一下(n>10),f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

我们来看个图:、

矩阵A                                                   矩阵B

0 1 0 0 0 0 0 0 0 0                                  f0                                  f1

0 0 1 0 0 0 0 0 0 0                                  f1                                  f2

0 0 0 1 0 0 0 0 0 0                                  f2                                  f3

0 0 0 0 1 0 0 0 0 0                *                f3  ---------->                f4

0 0 0 0 0 1 0 0 0 0                                  f4                                  f5

0 0 0 0 0 0 1 0 0 0                                  f5                                  f6

0 0 0 0 0 0 0 1 0 0                                  f6                                  f7

0 0 0 0 0 0 0 0 1 0                                  f7                                  f8

0 0 0 0 0 0 0 0 0 1                                  f8                                  f9

a9 a8 a7 a6 a5 a4 a3 a2 a1 a0                  f9                                  f10

我们看到规律了,每次要到下次个A*B,以此类推则由A*A*A.......A*B;

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int num[33][11][11],count;

void Matrix( int t, int m ) //二分法

{

   if( t==1 )

      return ;

   Matrix( t/2,m );

   if( t%2 )//奇数

   {

       int number[11][11]={0};

       count++; 

       for( int i=1; i<=10; i++ )

         for( int j=1; j<=10; j++ )

           for( int k=1; k<=10; k++ )

             num[count][i][j]=(num[count][i][j]+num[count-1][i][k]*num[count-1][k][j])%m;

          for( int i=1; i<=10; i++ )

            for( int j=1; j<=10; j++ )

               for( int k=1; k<=10; k++ )

                  number[i][j]=(number[i][j]+num[count][i][k]*num[1][k][j])%m;

       for( int i=1; i<=10; i++ )

       {

          for( int j=1; j<=10; j++ )

          {

           num[count][i][j]=number[i][j];

           }

       }

   }

   else//偶数

   {

      count++; 

       for( int i=1; i<=10; i++ )

       {

         for( int j=1; j<=10; j++ )

         {

           for( int k=1; k<=10; k++ )

             num[count][i][j]=(num[count][i][j]+num[count-1][i][k]*num[count-1][k][j])%m;    

         }

       } 

   }     

}

int main()

{

    int t,m;

    while( scanf( "%d%d",&t,&m )!=EOF )

    {

        memset( num,0,sizeof( num ) );

        for( int i=1; i<=9; i++ )//建立矩阵

        {

          num[1][i][i+1]=1;

        }

       

        for( int i=10;i>=1; i-- )

          scanf( "%d",&num[1][10][i] ); 

        if( t<10 )

            printf( "%d\n",t );

        else 

          {

              count=1;

              Matrix( t-9,m );

              int sum=0;

              for( int i=1; i<=10; i++ )

              {

                    sum=(sum+num[count][10][i]*(i-1))%m;

              }

              printf( "%d\n",sum );

          }       

    }

    return 0;    

}

  

你可能感兴趣的:(simple)