1 条题解
-
0
线性方程组求解解题思路
核心功能
使用克莱姆法则(Cramer's Rule)求解3×3线性方程组,并判断解的唯一性
实现步骤
一、输入阶段
- 读取3×3系数矩阵
a[][]
- 读取3维常数项向量
b[]
二、行列式计算
- 计算系数矩阵的行列式
A
(主函数中的cal()
) - 对每个变量x_i:
- 将系数矩阵第i列替换为常数项向量
- 计算新矩阵的行列式
ans[i]
三、解的情况判断
- 无唯一解情况:
- 当
A=0
时直接判定无唯一解
- 当
- 唯一解情况:
- 使用公式
x_i = ans[i]/A
计算各变量解 - 对解进行精度处理(绝对值<0.0005视为0)
- 使用公式
四、输出阶段
- 先输出4个行列式值(3个替换行列式+原行列式)
- 根据行列式值输出结论:
- 无唯一解提示
- 或保留3位小数的唯一解
关键算法
- 行列式计算:
|a b c| |d e f| = a(ei-fh) - b(di-fg) + c(dh-eg) |g h i|
- 克莱姆法则:
- x_i = det(A_i)/det(A)
- 其中A_i是用b替换A的第i列得到的矩阵
技术特点
-
数值处理:
- 自定义
val()
函数处理浮点误差 - 零值判断阈值设为±0.0005
- 自定义
-
内存高效:
- 复用同一个3×3矩阵进行计算
- 通过列交换实现矩阵替换
-
输出规范:
- 严格保留3位小数
- 不同情况有明确文字提示
复杂度分析
- 时间复杂度:O(1)(固定3×3矩阵)
- 空间复杂度:O(1)
该实现适用于需要快速求解小型线性方程组的场景,特别是需要判断解的存在唯一性的情况。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; long long a[3][3], b[3]; void input() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) scanf("%lld", &a[i][j]); scanf("%lld", &b[i]); } } long long cal() { return a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) - a[0][1] * (a[1][0] * a[2][2] - a[1][2] * a[2][0]) + a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]); } double val(double a) { if (a < 0.0005 && -0.0005 < a) return 0; return a; } void work() { long long A = cal(); long long ans[3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) swap(b[j], a[j][i]); ans[i] = cal(); for (int j = 0; j < 3; j++) swap(b[j], a[j][i]); } for (int i = 0; i < 3; i++) printf("%lld ", ans[i]); printf("%lld\n", A); if (A == 0) printf("No unique solution\n"); else { printf("Unique solution:"); for (int i = 0; i < 3; i++) printf(" %.3f", val(ans[i] * 1.0 / A)); putchar('\n'); } putchar('\n'); } int main() { //freopen("t.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { input(); work(); } return 0; }
- 读取3×3系数矩阵
- 1
信息
- ID
- 915
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者