zoukankan      html  css  js  c++  java
  • hdu 4965 Fast Matrix Calculation

    题目链接:

      http://acm.hdu.edu.cn/showproblem.php?pid=4965

    题目大意:

      给你两个矩阵,A矩阵是n*k,B矩阵是k*n,(其中n<=1000,k<=6),求(A*B)^(n*n)中每个数mod6之后的和。

    解题思路:

      根据n,k的取值范围,(A*B)^(n*n)= A*B*A*B*……*A*B,这样按照顺序计算定然TLE,由于矩阵相乘的结合性,我们可以把(A*B)^(n*n)= A*(B*A)^(n*n-1)*B,复杂度就大大减少。

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 using namespace std;
     7 
     8 const int maxn = 1000;
     9 #define LL int
    10 struct mat
    11 {
    12     int *p;//由于n的取值范围比较大,所以这里用动态申请内存
    13     int r, c;//由于n和k的大小不一样,所以这里要记录矩阵的长和宽,方便计算时候使用
    14 };
    15 int k, n;
    16 mat mul (mat a, mat b);
    17 mat pow (LL n, mat a, mat b);
    18 int add (mat a);
    19 int main ()
    20 {
    21     while (scanf ("%d %d", &n, &k), n+k)
    22     {
    23         int i, j;
    24         mat a, b, c;
    25 
    26         a.p = (int *) malloc (n*k*sizeof(int));
    27         b.p = (int *) malloc (n*k*sizeof(int));
    28         c.p = (int *) malloc (n*n*sizeof(int));
    29 
    30         for (i=0; i<n; i++)
    31             for (j=0; j<k; j++)
    32                 scanf ("%d", &a.p[i*k+j]);
    33         a.r = n, a.c = k;
    34 
    35         for (i=0; i<k; i++)
    36             for (j=0; j<n; j++)
    37                 scanf ("%d", &b.p[i*n+j]);
    38         b.r = k, b.c = n;
    39 
    40         c = mul (b, a);
    41         c = pow (n*n-2, c, c);
    42         c = mul (a, c);
    43         c = mul (c, b);
    44         printf ("%d
    ", add(c));
    45     }
    46     return 0;
    47 }
    48 
    49 mat mul (mat a, mat b)
    50 {
    51     int i, j, k;
    52     mat c;
    53     c.p = (int *)malloc(n*n*sizeof(int));
    54 
    55     c.r = a.r, c.c = b.c;
    56 
    57 
    58     for (i=0; i<c.r; i++)
    59         for (j=0; j<c.c; j++)
    60         {
    61             c.p[i*c.c+j] = 0;
    62             for (k=0; k<a.c; k++)
    63                 c.p[i*c.c+j] = (c.p[i*c.c+j] + a.p[i*a.c+k] * b.p[k*b.c+j]) % 6;
    64         }
    65     return c;
    66 }
    67 mat pow (LL n, mat a, mat b)
    68 {
    69     while (n)
    70     {
    71         if (n % 2)
    72         {
    73             b = mul (b, a);
    74         }
    75         a = mul (a, a);
    76         n /= 2;
    77     }
    78     return b;
    79 }
    80 int add (mat a)
    81 {
    82     int i, j, sum = 0;
    83     for (i=0; i<n; i++)
    84         for (j=0; j<n; j++)
    85             sum = sum + a.p[i*n+j] % 6;
    86     return sum;
    87 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Git回退---reset和revert
    XML解析
    SpringBoot学习day01
    Spring boot精要
    JS没有contains方法,可以用indexof实现
    git fetch 取回所有分支(branch)的更新(转)
    idea 设置注释模板
    git退出编辑模式
    git 提交代码到远程分支
    linux下,保存退出vim编辑器(转)
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4377381.html
Copyright © 2011-2022 走看看