hdu4920——Matrix multiplication(矩阵快速幂or循环外提)
来源:互联网 发布:软件测试ppt 编辑:程序博客网 时间:2024/05/16 23:52
Matrix multiplication
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Problem Description
Given two matrices A and B of size n×n, find the product of them.
bobo hates big integers. So you are only asked to find the result modulo 3.
bobo hates big integers. So you are only asked to find the result modulo 3.
Input
The input consists of several tests. For each tests:
The first line contains n (1≤n≤800). Each of the following n lines contain n integers -- the description of the matrix A. The j-th integer in the i-th line equals Aij. The next n lines describe the matrix B in similar format (0≤Aij,Bij≤109).
The first line contains n (1≤n≤800). Each of the following n lines contain n integers -- the description of the matrix A. The j-th integer in the i-th line equals Aij. The next n lines describe the matrix B in similar format (0≤Aij,Bij≤109).
Output
For each tests:
Print n lines. Each of them contain n integers -- the matrix A×B in similar format.
Print n lines. Each of them contain n integers -- the matrix A×B in similar format.
Sample Input
10120 12 34 56 7
Sample Output
00 12 1
题意:给出两个n*n的矩阵,求这两个矩阵的乘积,结果对3取余。
奇妙的题,循环外提巧妙AC
相关博客:http://blog.csdn.net/gogdizzy/article/details/9003369
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 805;
int a[N][N], b[N][N], ans[N][N];
int main()
{
int n, i, j, k;
while(~scanf("%d",&n))
{
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d",&a[i][j]);
a[i][j] %= 3;
}
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d",&b[i][j]);
b[i][j] %= 3;
}
memset(ans, 0, sizeof(ans));
for(k = 1; k <= n; k++) //经典算法中这层循环在最内层,放最内层会超时,但是放在最外层或者中间都不会超时,不知道为什么
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
ans[i][j] += a[i][k] * b[k][j];
//ans[i][j] %= 3; //如果在这里对3取余,就超时了
}
for(i = 1; i <= n; i++)
{
for(j = 1; j < n; j++)
printf("%d ", ans[i][j] % 3);
printf("%d\n", ans[i][n] % 3);
}
}
return 0;
}
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 805;
int a[N][N], b[N][N], ans[N][N];
int main()
{
int n, i, j, k;
while(~scanf("%d",&n))
{
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d",&a[i][j]);
a[i][j] %= 3;
}
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d",&b[i][j]);
b[i][j] %= 3;
}
memset(ans, 0, sizeof(ans));
for(k = 1; k <= n; k++) //经典算法中这层循环在最内层,放最内层会超时,但是放在最外层或者中间都不会超时,不知道为什么
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
ans[i][j] += a[i][k] * b[k][j];
//ans[i][j] %= 3; //如果在这里对3取余,就超时了
}
for(i = 1; i <= n; i++)
{
for(j = 1; j < n; j++)
printf("%d ", ans[i][j] % 3);
printf("%d\n", ans[i][n] % 3);
}
}
return 0;
}
另外:
解题思路:如果按照先求矩阵C 再求C的(N*N)肯定会超时,因为C有N行N列,最多为1000*1000*1000*log2(1000000)。但是我们可以用到一个矩阵的性质。矩阵虽然不满足交换律但是他满足结合律。这边C是A和B的矩阵乘积。C的N*N次方相当于(A*B)^(N*N) = A*B*A*B...*A*B 总共N*N个。即 原式 = A * (B*A)*(B*A)...(B*A)*B 总共有N*N-1个的B*A。然后我们就可以根据B*A来算了。这边K最多是6 所以算中间这一部分的值为6*6*6*log2(1000000-1).这样,我们使用矩阵快速幂,就不会超时了。
由于结构体里开不了1000*1000的大小,所以只开了6*6的矩阵。剩下的用普通的矩阵乘法计算。
#include <iostream>#include <queue>
#include <stack>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
using namespace std;
struct matrix
{
int ma[15][15];
int row,col;
};
matrix operator *(matrix a,matrix b)
{
matrix w;
memset(w.ma,0,sizeof(w.ma));
for (int i=0; i<a.row; i++)
for (int j=0; j<b.col; j++)
for (int h=0; h<a.col; h++)
w.ma[i][j]=(w.ma[i][j]+a.ma[i][h]*b.ma[h][j])%6;
w.row=a.row;
w.col=b.col;
return w;
}
matrix operator ^(matrix a,__int64 b)
{
matrix w;
for (int i=0; i<6; i++) for (int j=0; j<6; j++) w.ma[i][j]=(i==j);
w.row=6;
w.col=6;
while (b)
{
if (b&1) w=w*a;
a=a*a;
b>>=1;
}
return w;
}
int ans1[1111][1111];
int ans[1111][15];
int a[1111][15],b[15][1111];
matrix va;
int main()
{
__int64 n,k,i,j;
while (~scanf(" %I64d %I64d",&n,&k),(n|k))
{
for (i=0; i<n; i++)
for (j=0; j<k; j++) scanf(" %d",&a[i][j]);
for (i=0; i<k; i++)
for (j=0; j<n; j++) scanf(" %d",&b[i][j]);
for (int i=0; i<k; i++)
for (int j=0; j<k; j++)
{
va.ma[i][j]=0;
for (int h=0; h<n; h++)
va.ma[i][j]=(va.ma[i][j]+b[i][h]*a[h][j])%6;
}
va.row=k;
va.col=k;
__int64 m=n*n;
va=va^(m-1);
for (int i=0; i<n; i++)
for (int j=0; j<k; j++)
{
ans[i][j]=0;
for (int h=0; h<k; h++)
ans[i][j]=(ans[i][j]+a[i][h]*va.ma[h][j])%6;
}
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{
ans1[i][j]=0;
for (int h=0; h<k; h++)
ans1[i][j]=(ans1[i][j]+ans[i][h]*b[h][j])%6;
}
__int64 sum=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
sum+=(ans1[i][j]%6);
}
}
printf("%I64d\n",sum);
}
return 0;
}
0 0
- hdu4920——Matrix multiplication(矩阵快速幂or循环外提)
- HDU4920 Matrix multiplication 矩阵
- hdu4920 Matrix multiplication [矩阵乘法 压位 ]
- hdu4920 Matrix multiplication
- HDU4920:Matrix multiplication
- hdu4920 Matrix multiplication
- hdoj 4920 Matrix multiplication 【矩阵快速幂】
- HDU4920:Matrix multiplication(思维 & bitset)
- POJ 3233 Matrix Power Series(求矩阵幂的和——分块矩阵快速幂 or 二分递归+矩阵快速幂)
- hdu4920 Matrix multiplication 2014 Multi-University Training Contest 5
- HDU4920 Matrix multiplication (CPU cache对程序的影响)
- POJ 3318 Matrix Multiplication【矩阵相乘——随机化检测】
- poj 3233 Matrix Power Series 矩阵快速幂or二分
- 矩阵 ACdream1213 Matrix Multiplication
- ZOJ2316——Matrix Multiplication
- Codeforces_450B_Jzzhu and Sequences(循环节or矩阵快速幂)
- 【poj3233】Matrix Power Series——矩阵快速幂
- 【hdu5015】233 Matrix——矩阵快速幂
- Unity 自动添加tag,SortingLayers,Layer
- 哈密顿绕行世界问题 (深搜(记录路径))
- enum的使用
- HDU 4622 Reincarnation (区间不相同子串个数:字符串哈希 | 后缀数组 | 后缀自动机)
- Android 复制屏幕上画面内容
- hdu4920——Matrix multiplication(矩阵快速幂or循环外提)
- win8下Source Insight has not been installed completely问题的解决
- java-登陆注册案例
- 小知识--背景图片url是data:开头的
- 设计模式之建造者模式java(Builder)
- 优雅自定义Dialog
- MVC和MTV模式
- 第五次实验--数组一
- springboot链接1