题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3521
Time Limit: 24000/12000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Problem Description
We define e^A as following:
Where A is a n×n symmetric matrix with real elements, I is an identity matrix.
Give you matrix A, your task is to calculate e^A.
Input
There are several test cases;
Each test case begin with a line contains an integer n (1≤n≤100), the following n lines contain n×n symmetric matrix A. The rang of elements of A is (-100,100);
n=0 is the end of input and need not to proceed.
Output
For each test case, output n lines contain matrix eA , The value of elements of matrix eA must be accurate up to two decimal places. You may assume the range of elements of eA is (-10000,10000).
Sample Input
1
2
2
1 0
0 1
0
Sample Output
7.39
2.72 0.00
0.00 2.72
Problem solving report:
Description: 模拟计算一个e的A矩阵次方的公式,要求精度到小数点后两位。
Problem solving: 公式明显能看出,多项式后面的项开始变小,最终e的A次方收敛在一个值,根据数据范围估计50之后应该可以达到精度要求。
Accepted Code:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
const double eps = 1e-8;
struct mat {
double m[MAXN][MAXN];
}a, e;
int n;
mat mul(mat a, mat b) {
mat c = {0};
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
c.m[i][j] += a.m[i][k] * b.m[k][j];
return c;
}
int main() {
for (int i = 0; i < MAXN; i++)
e.m[i][i] = 1;
while (scanf("%d", &n), n) {
double k = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%lf", &a.m[i][j]);
mat ans = e, p = e;
for (int i = 1; i < 50; i++) {
k *= i;
p = mul(p, a);
for (int j = 0; j < n; j++)
for (int l = 0; l < n; l++)
ans.m[j][l] += p.m[j][l] / k;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
printf("%.2f ", ans.m[i][j]);
printf("\n");
}
}
return 0;
}