洛谷P2455 [SDOI2006]线性方程组(高斯消元)
程序员文章站
2022-09-28 08:17:37
题目描述 已知n元线性一次方程组。 其中:n<=50, 系数是[b][color=red]整数<=100(有负数),bi的值都是整数且<300(有负数)(特别感谢U14968 mmqqdd提出题目描述的说明)(redbag:是mqd自己要我写的= =)[/color][/b]. 编程任务: 根据输入 ......
题目描述
已知n元线性一次方程组。
其中:n<=50, 系数是[b][color=red]整数<=100(有负数),bi的值都是整数且<300(有负数)(特别感谢U14968 mmqqdd提出题目描述的说明)(redbag:是mqd自己要我写的= =)[/color][/b].
编程任务:
根据输入的数据,编程输出方程组的解的情况。
输入输出格式
输入格式:
第一行:未知数的个数。以下n行n+1列:分别表示每一格方程的系数及方程右边的值。
输出格式:
如果方程组无实数解输出-1;
如果有无穷多实数解,输出0;
如果有唯一解,则输出解(小数点后保留两位小数)。
输入输出样例
输入样例#1: 复制
3 2 -1 1 1 4 1 -1 5 1 1 1 0
输出样例#1: 复制
x1=1.00 x2=0 x3=-1.00
裸的高斯消元
不过这题真的是,往死里卡精度。。
注意先判无解,再判无穷
// luogu-judger-enable-o2 #include<cstdio> #include<algorithm> const double eps = 1e-9; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') { if(c == '-')f = -1; c = getchar(); } while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } const int MAXN = 101; int N; double a[MAXN][MAXN]; double Ans[MAXN]; double fabs(double x) {return x < 0 ? -x : x;} void Gauss() { for(int i = 1; i <= N; i++) { int mx = i; for(int j = i + 1; j <= N; j++) if(fabs(a[j][i]) > fabs(a[mx][i])) mx = j; if(mx != i) std::swap(a[mx], a[i]); if(fabs(a[i][i]) >= eps) for(int j = 1; j <= N; j++) { if(i == j) continue; double temp = a[j][i] / a[i][i]; for(int k = 1; k <= N + 1; k++) a[j][k] -= temp * a[i][k]; } } int NoSolution = 0, ManySolution = 0; for(int i = 1; i <= N; i++) { int num = 0; for(int j = 1; j <= N + 1; j++) if(a[i][j] == 0) num ++; else break; if(num == N + 1) ManySolution = 1; if(num == N && a[i][N+1] != 0) NoSolution = 1; } if(NoSolution) {printf("-1");return ;} if(ManySolution) {printf("0");return ;} for(int i = N; i >= 1; i--) { Ans[i] = a[i][N+1] / a[i][i]; for(int j = i; j >= 1; j--) a[j][N+1] -= a[j][i] * Ans[i]; } for(int i = 1; i <= N; i++) printf("x%d=%.2lf\n",i,Ans[i]); } int main() { #ifdef WIN32 freopen("a.in", "r", stdin); #endif N = read(); for(int i = 1; i <= N; i++) for(int j = 1; j <= N + 1; j++) a[i][j] = read(); Gauss(); return 0; }
下一篇: 测试merge效率