hpu 1183 线代+hdu 4965 Fast Matrix Calculation【矩阵快速幂+思维】

来源:互联网 发布:淘宝男士夏装 编辑:程序博客网 时间:2024/06/06 07:10

1183: 线代 [矩阵]

时间限制: 10 Sec 内存限制: 128 MB

题目描述

学过线性代数后,Ocean又有了新的难题。
现在Ocean有两个矩阵AABB,大小分别为nxn∗xxmx∗m。现在Ocean想知道新矩阵C=(AB)tC=(A∗B)t
但是输出矩阵太麻烦了,你只需要告诉他CC矩阵元素之和对666666取余的结果即可。
所有测试数据保证nn 等于 mm。请认真读题

C=ABC=A∗B程序实现:
假设AA矩阵是nxn∗x的,BB矩阵是xmx∗m的,则得到的CC矩阵是nmn∗m的。
程序实现C=ABC=A∗B如下:
int n, x, m;int A[1001][10], B[10][1001], C[1001][1001];int i, j, k;for(i = 0; i < n; i++) {    for(j = 0; j < m; j++) {        C[i][j] = 0;    }}for(i = 0; i < n; i++) {    for(k = 0; k < x; k++) {        if(A[i][k] == 0) continue;        for(j = 0; j < m; j++) {            C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % 666;        }    }}

输入

第一行输入一个整数TT,代表有TT组测试数据。
每组数据占多行,第一行依次输入四个整数nxmtn,x,m,t分别代表上面提到的信息。
接下来有nn行,每行输入xx个元素代表AA矩阵。
后面再有xx行,每行输入mm个元素代表BB矩阵。

注:1<=T<=1001<=nmt<=10001<=x<=61<=1<=T<=100,1<=n,m,t<=1000,1<=x<=6,1<=矩阵元素 <=66<=66。

输出

输出一个整数,代表CC矩阵元素之和对666666取余后的结果。

样例输入

210 3 10 10001 1 11 1 11 1 11 1 11 1 11 1 11 1 11 1 11 1 11 1 12 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 22 2 2 2 2 2 2 2 2 210 4 10 10001 2 3 41 2 3 41 2 3 41 2 3 41 2 3 41 2 3 41 2 3 41 2 3 41 2 3 41 2 3 47 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 

样例输出

396340
题目链接

思路:
一开始用结构体去存,应该是爆栈了,那只能用数组模拟了。快速幂+矩阵相乘,由于n,m比较大且相等,直接写肯定TLE,本题有个技巧需要用:A * B * A * B * A * B = A *(B * A * B * A)* B,这样就把  n * m的t次方  矩阵化为:n * x * ( x * x 的 t - 1 次方) * x * m,问题就解决了。

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;typedef long long LL;const int mod = 666;int T, n, m, x, t;int A[1010][1010], B[1010][1010], C[1010][1010], D[1010][1010], E[1010][1010];void mat_mul() {memset(C, 0, sizeof(C));for(int i = 0; i < x; i++) {for(int j = 0; j < n; j++) {for(int k = 0; k < x; k++) {C[i][k] = (C[i][k] + B[i][j] * A[j][k]) % mod;}} }}int main() {scanf("%d", &T);while(T--) {scanf("%d %d %d %d", &n, &x, &m, &t);for(int i = 0; i < n; i++)for(int j = 0; j < x; j++) scanf("%d", &A[i][j]);for(int i = 0; i < x; i++)for(int j = 0; j < m; j++)scanf("%d", &B[i][j]);mat_mul();memset(D, 0, sizeof(D));for(int i = 0; i <= x; i++) { //初始化单位矩阵 D[i][i] = 1;}t--;while(t) {if(t & 1) {memset(E, 0, sizeof(E)); //用一个矩阵做中间值传递 for(int i = 0; i < x; i++) {for(int j = 0; j < x; j++) {for(int k = 0; k < x; k++) {E[i][k] = (E[i][k] + D[i][j] * C[j][k]) % mod;}}}for(int i = 0; i < x; i++) {for(int j = 0; j < x; j++ ) {D[i][j] = E[i][j];}}}memset(E, 0, sizeof(E));for(int i = 0; i < x; i++) {for(int j = 0; j < x; j++) {for(int k = 0; k < x; k++) {E[i][k] = (E[i][k] + C[i][j] * C[j][k]) % mod;}}}for(int i = 0; i < x; i++) {for(int j = 0; j < x; j++) {C[i][j] = E[i][j];}}t >>= 1;}memset(C, 0, sizeof(C));for(int i = 0; i < n; i++) {for(int j = 0; j < x; j++) {for(int k = 0; k < x; k++) {C[i][k] = (C[i][k] + A[i][j] * D[j][k]) % mod;}} }memset(D, 0, sizeof(D));for(int i = 0; i < n; i++) {for(int j = 0; j < x; j++) {for(int k = 0; k < m; k++) {D[i][k] = (D[i][k] + C[i][j] * B[j][k]) % mod;}} }int sum = 0;for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)sum = (sum + D[i][j]) % mod;printf("%d\n", sum % mod);}return 0;} 

类似这个题目:

HDU 4965

相同的处理方式

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define max_n 1010const int mod = 6;using namespace std;typedef long long LL;int A[max_n][max_n], B[max_n][max_n], C[max_n][max_n], D[max_n][max_n], E[max_n][max_n];int main() {int n, m;while(scanf("%d %d", &n, &m) && (n + m)) {for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {scanf("%d", &A[i][j]);}}for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {scanf("%d", &B[i][j]);}}memset(C, 0, sizeof(C));for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {for(int k = 0; k < m; k++) {C[i][k] = (C[i][k] + B[i][j] * A[j][k]) % mod;}}}int t = n * n;t--;memset(D, 0, sizeof(D));for(int i = 0; i < m; i++) {D[i][i] = 1;}while(t) {if(t & 1) {memset(E, 0, sizeof(E));for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {for(int k = 0; k < m; k++) {E[i][k] = (E[i][k] + C[i][j] * D[j][k]) % mod;}}}for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {D[i][j] = E[i][j];}}}memset(E, 0, sizeof(E));for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {for(int k = 0; k < m; k++) {E[i][k] = (E[i][k] + C[i][j] * C[j][k]) % mod;}}}for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {C[i][j] = E[i][j];}}t >>= 1;}memset(E, 0, sizeof(E));for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {for(int k = 0; k < m; k++) {E[i][k] = (E[i][k] + A[i][j] * D[j][k]) % mod;}}}memset(D, 0, sizeof(D));for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {for(int k = 0; k < n; k++) {D[i][k] = (D[i][k] + E[i][j] * B[j][k]) % mod;}}}int sum = 0;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {sum += D[i][j];}}printf("%d\n", sum);}return 0;}


阅读全文
1 0
原创粉丝点击