hpu 1183 线代+hdu 4965 Fast Matrix Calculation【矩阵快速幂+思维】
来源:互联网 发布:淘宝男士夏装 编辑:程序博客网 时间:2024/06/06 07:10
1183: 线代 [矩阵]
时间限制: 10 Sec 内存限制: 128 MB题目描述
学过线性代数后,Ocean又有了新的难题。
现在Ocean有两个矩阵A A和B B,大小分别为n∗x n∗x和x∗m x∗m。现在Ocean想知道新矩阵C=(A∗B)t C=(A∗B)t。
但是输出矩阵太麻烦了,你只需要告诉他C C矩阵元素之和对666 666取余的结果即可。
所有测试数据保证n n 等于 m m。请认真读题
C=A∗B C=A∗B程序实现:
假设A A矩阵是n∗x n∗x的,B B矩阵是x∗m x∗m的,则得到的C C矩阵是n∗m n∗m的。
程序实现C=A∗B C=A∗B如下:
现在Ocean有两个矩阵
但是输出矩阵太麻烦了,你只需要告诉他
所有测试数据保证
假设
程序实现
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; } }}
输入
第一行输入一个整数T T,代表有T T组测试数据。
每组数据占多行,第一行依次输入四个整数n,x,m,t n,x,m,t分别代表上面提到的信息。
接下来有n n行,每行输入x x个元素代表A A矩阵。
后面再有x x行,每行输入m m个元素代表B B矩阵。
注:1<=T<=100,1<=n,m,t<=1000,1<=x<=6,1<= 1<=T<=100,1<=n,m,t<=1000,1<=x<=6,1<=矩阵元素 <=66。 <=66。
每组数据占多行,第一行依次输入四个整数
接下来有
后面再有
注:
输出
输出一个整数,代表C C矩阵元素之和对666 666取余后的结果。
样例输入
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
- hpu 1183 线代+hdu 4965 Fast Matrix Calculation【矩阵快速幂+思维】
- 【HDU】4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix Calculation【矩阵快速幂】
- hdu 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix Calculation 矩阵快速幂
- hdu 4965 Fast Matrix Calculation(矩阵快速幂)
- HDU 4965 Fast Matrix Calculation | 矩阵快速幂
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix Calculation【矩阵快速幂模板】
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix Calculation(矩阵快速幂)
- HDU-4965 Fast Matrix Calculation (矩阵快速幂)
- HDU 4965 Fast Matrix Calculation (矩阵快速幂
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- 【矩阵快速幂+矩阵运算性质】Fast Matrix Calculation HDU
- CPU的缓存L1、L2、L3
- MainActivity
- Gym
- 如何使用谷歌
- 数据库连接池c3p0介绍与使用
- hpu 1183 线代+hdu 4965 Fast Matrix Calculation【矩阵快速幂+思维】
- Android混淆打包 出现release/jars/3/1f/main.jar'
- js实现身份证校验----Ctrl+c/Ctrl+v可用,无需改动
- break continue作用于外层循环
- Can not find scala.async.Async.{async, await}
- spring boot中的java配置中的注解
- linux下kill cpu占用高的程序
- POJ 1861 Network (Kruskal算法)
- 【MySQL集群】——在Windows环境下配置MySQL集群