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\n", 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 }

 

posted @ 2015-03-30 10:44  罗茜  阅读(181)  评论(2编辑  收藏  举报