逆序数&行列式&矩阵乘法&逆矩阵【线性代数】
2017-11-15 21:58
429 查看
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cmath> #include<map> #include<string> #include<functional> using namespace std; const int maxn = 12; string str; map<string, int>mp; map<int, string>rmp; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } struct Dmt {//行列式 int x; int y; int a[maxn][maxn]; }; struct Mat {//矩阵 int x; int y; int a[maxn][maxn]; }; int determinant_1(Dmt tmp) { int a_1 = tmp.a[1][1]; return a_1; } int determinant_2(Dmt tmp) { int a_1 = tmp.a[1][1] * tmp.a[2][2]; int a_2 = tmp.a[1][2] * tmp.a[2][1]; return a_1 - a_2; } int determinant_3(Dmt tmp) { int a_1 = tmp.a[1][1] * tmp.a[2][2] * tmp.a[3][3]; int a_2 = tmp.a[1][2] * tmp.a[2][3] * tmp.a[3][1]; int a_3 = tmp.a[1][3] * tmp.a[2][1] * tmp.a[3][2]; int a_4 = tmp.a[1][3] * tmp.a[2][2] * tmp.a[3][1]; int a_5 = tmp.a[1][1] * tmp.a[2][3] * tmp.a[3][2]; int a_6 = tmp.a[1][2] * tmp.a[2][1] * tmp.a[3][3]; return a_1 + a_2 + a_3 - a_4 - a_5 - a_6; } int get_determinant(Dmt tmp, int ans)//ans——当前行列式的值 { Dmt newtmp; if (tmp.x == 1 && tmp.y == 1) return determinant_1(tmp); if (tmp.x == 2 && tmp.y == 2) return determinant_2(tmp); if (tmp.x == 3 && tmp.y == 3) return determinant_3(tmp); //按照最后一行的代数余子式展开~ newtmp.x = tmp.x - 1; //cout << newtmp.x << endl; newtmp.y = tmp.y - 1; //cout << newtmp.y << endl; int cnt = ans; for (int i = 1; i <= tmp.x; i++)//按照最后一行展开成代数余子式! { for (int j = 1; j <= tmp.x - 1; j++) { int cs = 1; for (int k = 1; k <= tmp.y; k++) { if (k == i) continue; newtmp.a[j][cs] = tmp.a[j][k]; cs++; } } cnt += (int)pow(-1, tmp.y + i)*tmp.a[tmp.y][i] * get_determinant(newtmp, 0); } return cnt; } void solve_determinant() { printf("请输入行列式的行数、列数\n"); Dmt test; // int x; int y; scanf("%d%d", &test.x, &test.y); printf("读取成功,请输入行列式\n"); for (int i = 1; i <= test.x; i++) { for (int j = 1; j <= test.y; j++) { scanf("%d", &test.a[i][j]); } } printf("%d\n", get_determinant(test, 0)); } int get_inversion_pair(int cnt, int b[]) { int ans = 0; for (int i = 1; i <= cnt; i++) { for (int j = i + 1; j <= cnt; j++) { if (b[j] < b[i]) ans++; } } return ans; } void solve_inversion_num() { printf("请输入序列的长度\n"); int n; int a[12]; scanf("%d", &n); printf("请输入序列元素(请用空格分隔)\n"); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } printf("%d\n", get_inversion_pair(n, a)); } Mat get_matrix_multiplication(Mat A, Mat B)//预处理判断矩阵是否可以相乘 { Mat newtmp; int m = A.x, s = A.y, n = B.y; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { newtmp.a[i][j] = 0;//矩阵初始化 } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= s; k++) { newtmp.a[i][j] += A.a[i][k] * B.a[k][j]; } } } return newtmp; } void solve_matrix_multiplication() { Mat A, B, ans; printf("请输入矩阵A的长和宽\n"); scanf("%d %d", &A.x, &A.y); printf("请输入矩阵B的长和宽\n"); scanf("%d %d", &B.x, &B.y); if (A.y != B.x) { printf("输入非法 无法相乘\n"); return; } printf("请输入矩阵A\n"); for (int i = 1; i <= A.x; i++) { for (int j = 1; j <=A.y; j++) { scanf("%d", &A.a[i][j]); } } printf("读取成功,请输入矩阵B\n"); for (int i = 1; i <= B.x; i++) { for (int j = 1; j <= B.y; j++) { scanf("%d", &B.a[i][j]); } } int m = A.x, s = A.y, n = B.y; ans = get_matrix_multiplication(A, B);//完成计算 得到新矩阵ans printf("%d %d\n", m, n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (j!=1) printf(" "); printf("%d", ans.a[i][j]); } printf("\n"); } } void get_inverse_matrix(Mat A)//根据公式A^-1=1/|A|*伴随A { Dmt tmp;//行列式 Mat ans;//矩阵 Dmt cnt;//行列式 cnt.x = A.x; cnt.y = A.y; ans.x = A.x; ans.y = A.y; tmp.x = A.x - 1; tmp.y = A.y - 1; for (int i = 1; i <= cnt.x; i++) { for (int j = 1; j <= cnt.y; j++) { cnt.a[i][j] = A.a[i][j]; } } for (int i = 1; i <= A.x; i++) { for (int j = 1; j <= A.y; j++) { int cs = 1; int ct = 1; for (int k = 1; k <= A.x; k++) { ct = 1; if (k == i) continue; for (int p = 1; p <= A.y; p++) { if (p == j) continue; tmp.a[cs][ct] = A.a[k][p]; ct++; } cs++; } //cout << cs << " " << ct << endl; ans.a[i][j] = (int)pow(-1, i + j)*get_determinant(tmp, 0); //cout << ans.a[i][j] << endl; } } int hlsA = get_determinant(cnt, 0); printf("%d\n", hlsA); for (int i = 1;i<=ans.x;i++) { for (int j=1;j<=ans.y;j++) { if (j != 1) printf(" "); int temp = gcd(hlsA, ans.a[j][i]); if (ans.a[j][i] % hlsA == 0) { printf("%d ", ans.a[j][i] / hlsA); } else { printf("%d/%d", ans.a[j][i] / temp, hlsA / temp); } } printf("\n"); } } void solve_inverse_matrix() { Mat A, B; printf("请输入矩阵的长和宽\n"); scanf("%d%d", &A.x, &A.y); printf("读取成功,请输入矩阵的元素\n"); for (int i = 1; i <= A.x; i++) { for (int j = 1; j <= A.y; j++) { scanf("%d", &A.a[i][j]); } } get_inverse_matrix(A); /*for (int i = 1; i <= B.x; i++) { for (int j = 1; j <= B.y; j++) { if (j != 1) printf(" "); printf("%d", B.a[i][j]); } printf("\n"); }*/ } int main() { printf("祝您考试取得佳绩!\n"); mp.clear(); mp["hls"] = 1;//行列式 mp["nxs"] = 2;//逆序数 mp["jzcf"] = 3;//矩阵乘法 mp["njz"] = 4;//逆矩阵 //cin.ignore(); while (cin>>str) { //printf("%d\n", mp.count(str)); if (mp.count(str)) { printf("读取成功\n"); if (str == "hls") solve_determinant(); else if (str == "nxs") solve_inversion_num(); else if (str == "jzcf") solve_matrix_multiplication(); else if (str == "njz") solve_inverse_matrix(); } else { printf("读取失败,请重新输入\n"); } } system("pause"); return 0; }
相关文章推荐
- [Vijos 1194] Domino · 矩阵乘法 (附运算符优先级表)
- 【线性代数】矩阵的乘法与求逆
- 【bzoj】3329: Xorequ 【DP】【快速幂&&矩阵乘法】
- 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法
- POJ 3744 Scout YYF I (概率DP & 期望 + 矩阵乘法)
- 线性代数-矩阵乘法的推导
- 线性代数--矩阵乘法
- poj3150 && LA3704 Cellular Automaton 矩阵乘法 + 循环矩阵性质
- [hdu2276][矩阵乘法]Kiki & Little Kiki 2
- hdu 2276 Kiki & Little Kiki 2(矩阵乘法)
- hdu 3221 矩阵乘法和 A^x = A^(x % Phi(C) + Phi(C)) (mod C)(x>=phi(c))
- bzoj2553 禁忌 AC自动机&矩阵乘法
- [Vijos 1067] Warcraft III 守望者的烦恼 · 矩阵乘法
- [BZOJ 2875 & Vijos 1725] NOI 2012 随机数生成器 · 矩阵乘法+快速乘法
- [BZOJ 1875] SDOI 2009 HH去散步 · 矩阵乘法
- 快速乘法&快速幂&矩阵快速幂简单讲解
- 2009 英特尔® 线程挑战赛 第七题 矩阵乘法
- 【矩阵乘法】逆矩阵
- Matlab与线性代数 -- 矩阵的乘法
- HDU 2276 Kiki & Little Kiki 2 矩阵构造和乘法