标签:
题目链接:
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 }
hdu 4965 Fast Matrix Calculation
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4377381.html