Matrix multiplication (VII): Some other typical applications

      Several essays described in the foregoing method using the matrix multiplication (in particular the application of fast exponentiation) solution rapid recurrence evaluation, substitutions, and other geometric transformation problem. Matrix multiplication is actually applied far more than that, here are some other typical applications of the matrix multiplication by a few examples.

[Example 1] number of lanes.

      Given a directed graph, Q k steps just go from point A (edge ​​to allow repeated passes) program number reaches the point B mod p value.

      (1) programming ideas.

      This problem is a typical method used in the matrix multiplication of graph theory.
      Given a directed graph, the adjacency matrix A can be obtained in the figure, in adjacency matrix A, A (i, j) = 1 if and only if there is an edge i-> j. If i-> j edges directly connected does not exist, A (i, j) = 0 .

      So that C = A * A, then C (i, j) = ΣA (i, k) * A (k, j), in fact, equivalent from point i to point j just after a number of paths of two sides (k is transit point).

      Similarly, C * A = A * A * A i-th row j-th column can represent from i to j number of paths through the three sides. Similarly, if the required number of k steps through a path, only exponentiation arithmetic using fast A ^ k can be determined.

 

      (2) source.

#include <stdio.h>
#include <string.h>
#define MOD 1000
struct Matrix
{
      int mat[21][21]; // 存储矩阵中各元素
};
Matrix matMul(Matrix a ,Matrix b,int n,int m)
{
      Matrix c;
      memset(c.mat,0,sizeof(c.mat));
      int i,j,k;
      for (k = 1; k<=n ; k++)
          for (i=1 ;i<=n ; i++)
               if (a.mat[i][k]!=0)
                    for (j = 1 ;j<=n ;j++)
                        c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % m;
      return c;
}
Matrix quickMatPow(Matrix a ,int n,int b,int m) // n阶矩阵a快速b次幂
{
      Matrix c;
      memset(c.mat ,0 ,sizeof(c.mat));
      int i;
      for (i = 1 ;i <= n ;i++)
           c.mat[i][i] = 1;
      while (b!=0)
      {
            if (b & 1)
                c = matMul(c ,a ,n,m); // c=c*a;
            a = matMul(a ,a ,n,m); // a=a*a
            b /= 2;
      }
      return c;
}
int main()
{
      int n,m,s,t,nCase,a,b,k,i;
      Matrix p,ans;
      while (scanf("%d%d",&n,&m) && n+m!=0)
      {
            memset(p.mat,0,sizeof(p.mat));
            for (i=1;i<=m;i++)
            {
                 scanf("%d%d",&s,&t);
                 p.mat[s+1][t+1]=1;
            }
            scanf("%d",&nCase);
            for (i=1;i<=nCase;i++)
            {
                  scanf("%d%d%d",&a,&b,&k);
                  ans=quickMatPow(p,n,k,MOD);
                  printf("%d\n" ,ans.mat[a+1][b+1]);
             }
      }
      return 0;
}

This source code submitted to the HDU 2157 "How MANY Ways ??" , you can be Accepted.

 

       We know that construction is good pan, zoom or rotate after the transformation matrix, geometric transformation can be achieved; after a good permutation matrix structure, the replacement operation can be achieved. Thus, in some issues, we can also change the status of the case, to construct a state transition matrix to solve some kind of problem state transformation.

[Example 2] state of the lamp.

     N-lamp arranged in a row, the switch state is known, 0 represents off lights, lights represents. Every second: first i (1 <= i <= n) light lamp according to the lamp where the switch just to the left of the change, if the light is on the left, it will change, if the lamp is turned off to the left, it remains original state. The left side of the first lamp is the last lamp. Q m n seconds after full state lamp.

      (1) programming ideas.
      Good results configuration state transition matrix P, P ^ m is the state transition matrix after m seconds. State transition matrix and then dividing by n column vector lamp initial state S n to obtain the final state of the lamp.

      (2) source.

#include <stdio.h>
#include <string.h>
#define MOD 2
struct Matrix
{
      int mat[101][101]; // 存储矩阵中各元素
};
Matrix matMul(Matrix a ,Matrix b,int n)
{
     Matrix c;
     memset(c.mat,0,sizeof(c.mat));
     int i,j,k;
     for (k = 1; k<=n ; k++)
         for (i=1 ;i<=n ; i++)
             if (a.mat[i][k]!=0)
                 for (j = 1 ;j<=n ;j++)
                     c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
     return c;
}
Matrix quickMatPow(Matrix a ,int n,int b) // n阶矩阵a快速b次幂
{
      Matrix c;
      memset(c.mat ,0 ,sizeof(c.mat));
      int i;
      for (i = 1 ;i <= n ;i++)
           c.mat[i][i] = 1;
      while (b!=0)
     {
           if (b & 1)
              c = matMul(c ,a ,n); // c=c*a;
           a = matMul(a ,a ,n); // a=a*a
           b /= 2;
      }
      return c;
}
int main()
{
      int m,n,i,j,s;
      char f[101];
      int temp[101],ans[101];
      Matrix p;
      while(scanf("%d" ,&m)!=EOF)
       {
            scanf("%s",f);
            n=strlen(f);
            for (i=1;i<=n;i++)
                temp[i]=f[i-1]-'0';
            memset(p.mat,0,sizeof(p.mat));
            p.mat[1][1]=p.mat[1][n]=1;
            for (i=2;i<=n;i++)
                   p.mat[i][i-1]=p.mat[i][i]=1;
            p = quickMatPow(p,n,m);
            for (i=1;i<=n;i++)
             {
                   s=0;
                   for (j=1;j<=n;j++)
                        s+=p.mat[i][j]*temp[j];
                   ans[i]=s%MOD;
            }
            for (i=1;i<=n;i++)
                 printf("%d" ,ans[i]);
            printf("\n");
      }
      return 0;
}

     This source code submitted to the HDU 2276 "Little Kiki Kiki & 2" , can be Accepted.

 

Guess you like

Origin www.cnblogs.com/cs-whut/p/11479080.html