自信地把那个模板敲下来,只有60。
因为我又不知道如何判无解或者无穷解。
然后在漫长的查资料过程中,我改变了我的写法。
虽然原来那种解法理解起来也很容易,但是过不了,所以我决定抄另一种高斯消元模板。
代码从这里抄的:https://blog.csdn.net/yangrui2002/article/details/79341513
原来的方法需要回带才可以解决,但是如果使用上面的,就不需要回带。每一条方程式都是最标准的形式。
要修改的地方就把好多的i改成1而已。。。
然后有很显然的判无解和判无穷解方法:
无解。当未知数系数为0,而常数项不为0时,显然无解。
无穷解。当未知数系数和常数项都为0时,有无穷解。
PS:如何判断这个数与0的关系?用eps。
注意:先判无解,后判无穷解。
然后就没事了。
听dalao说:NOIP里面的高斯消元都是模板题。I hope so.
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
const int maxn = 105;
const double eps = 1e-7;
double a[maxn][maxn];
double ans[maxn];
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n + 1; j++)
scanf("%lf", &a[i][j]);
for(int i = 1; i <= n; i++)
{
int r = i;
for(int j = i + 1; j <= n; j++)
{
if(fabs(a[j][i]) > fabs(a[r][i])) r = j;
}
if(r != i) std::swap(a[r],a[i]);
if(fabs(a[i][i]) < eps) continue;
double div = a[i][i];
for(int j = 1; j <= n + 1; j++) a[i][j] /= div;
for(int j = 1; j <= n; j++)
{
if(i == j) continue;
div = a[j][i];
for(int k = 1; k <= n + 1; k++)
{
a[j][k] -= a[i][k] * div;
}
}
}
/*
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n + 1; j++)
{
printf("%.2lf ", a[i][j]);
}
printf("\n");
}
*/
bool opt1 = false, opt2 = false;
for(int i = 1; i <= n; i++)
{
int j = 1;
while(fabs(a[i][j]) < eps && j <= n + 1) j++;
if(j > n + 1) opt1 = true;
else if(j == n + 1) opt2 = true;
}
if(opt2)
{
printf("-1\n"); return 0;
}
if(opt1)
{
printf("0\n"); return 0;
}
for(int i = 1; i <= n; i++)
{
printf("x%d=", i);
if(fabs(a[i][n + 1]) < eps) printf("0\n");
else printf("%.2lf\n", a[i][n + 1]);
}
return 0;
}
原文:https://www.cnblogs.com/Garen-Wang/p/9388410.html