hpu 1183 线代+hdu 4965 Fast Matrix Calculation【矩阵快速幂+思维】
2017-08-18 09:19
232 查看
1183: 线代 [矩阵]
时间限制: 10 Sec 内存限制:128 MB
题目描述
学过线性代数后,Ocean又有了新的难题。现在Ocean有两个矩阵AA和BB,大小分别为n∗xn∗x和x∗mx∗m。现在Ocean想知道新矩阵C=(A∗B)tC=(A∗B)t。
但是输出矩阵太麻烦了,你只需要告诉他CC矩阵元素之和对666666取余的结果即可。
所有测试数据保证nn 等于 mm。请认真读题
C=A∗BC=A∗B程序实现:
假设AA矩阵是n∗xn∗x的,BB矩阵是x∗mx∗m的,则得到的CC矩阵是n∗mn∗m的。
程序实现C=A∗BC=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组测试数据。每组数据占多行,第一行依次输入四个整数n,x,m,tn,x,m,t分别代表上面提到的信息。
接下来有nn行,每行输入xx个元素代表AA矩阵。
后面再有xx行,每行输入mm个元素代表BB矩阵。
注: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。
输出
输出一个整数,代表CC矩阵元素之和对666666取余后的结果。
样例输入
2 10 3 10 1000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 10 4 10 1000 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 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 7
样例输出
396 340
题目链接
思路:
一开始用结构体去存,应该是爆栈了,那只能用数组模拟了。快速幂+矩阵相乘,由于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 1010
const 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;
}
相关文章推荐
- hdoj 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix(矩阵快速幂)
- 【HDU】4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)
- Fast Matrix Calculation HDU - 4965 (矩阵快速幂)
- HDU 4965 Fast Matrix Calculation (矩阵快速幂
- 【矩阵快速幂+矩阵运算性质】Fast Matrix Calculation HDU - 4965
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
- HDU 4965 Fast Matrix Calculation(矩阵快速幂)
- hdu 4965 Fast Matrix Calculation(矩阵快速幂)2014多校训练第9场
- hdu 4965 Fast Matrix Calculation 快速矩阵幂
- Fast Matrix Calculation HDU - 4965(矩阵快速幂)
- 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 2014多校9 矩阵快速幂+机智的矩阵结合律