Rusalka @ 2020-08-10 20:05:47
我在做这道题的时候最开始写的是这样的:
inline bool gauss()
{
for(int i=1;i<=n;i++)
{
int r = i;
for(int j=i+1;j<=n;j++)
if(check(r, j, i)) // 判断是否需要交换,和本帖的问题无关,check 函数的实现基本同第一篇题解
r = j;
if(r != i) swap(a[i], a[r]);
if(fabs(a[i][i]) < eps) continue;
for(int j=i+1;j<=n;j++)
{
double div = a[j][i]/a[i][i];
for(int k=i;k<=n+1;k++)
a[j][k] -= div*a[i][k];
}
}
for(int i=n;i>=1;i--)
{
if(a[i][i] < eps) continue;
for(int j=i+1;j<=n;j++)
a[i][n+1] -= a[j][n+1]*a[i][j];
a[i][n+1] /= a[i][i];
}
bool no = 0, any = 0;
for(int i=1;i<=n;i++)
{
if(fabs(a[i][i]) < eps && fabs(a[i][n+1]) > eps) no = 1;
if(fabs(a[i][i]) < eps && fabs(a[i][n+1]) < eps) any = 1;
}
if(no)
{
puts("-1");
return 0;
}
if(any)
{
puts("0");
return 0;
}
return 1;
}
为了节省空间只保留关键部分。
这份代码只能收获 70pts 的好成绩,有把多解判成无解的,也有把有唯一解判成无解的,还有输出错误解的。。。
所以我尝试了另外一种写法,具体是把上一份代码中的
for(int i=1;i<=n;i++)
{
int r = i;
for(int j=i+1;j<=n;j++)
if(check(r, j, i))
r = j;
if(r != i) swap(a[i], a[r]);
if(fabs(a[i][i]) < eps) continue;
for(int j=i+1;j<=n;j++)
{
double div = a[j][i]/a[i][i];
for(int k=i;k<=n+1;k++)
a[j][k] -= div*a[i][k];
}
}
替换成
for(int i=1;i<=n;i++)
{
int r = i;
for(int j=i+1;j<=n;j++)
if(check(r, j, i))
r = j;
if(r != i) swap(a[i], a[r]);
if(fabs(a[i][i]) < eps) continue;
double div = a[i][i];
for(int j=i;j<=n+1;j++)
a[i][j] /= div;
for(int j=i+1;j<=n;j++)
{
div = a[j][i];
for(int k=i;k<=n+1;k++)
{
a[j][k] -= div*a[i][k];
}
}
}
也就是在更改了消成上三角矩阵的时候的代码。
这份代码能收获 90pts 的好成绩,错误的地方是第 9 个测试点,把多解判成无解。
我百思不得其解,于是参考了第一篇题解,发现在计算主对角线的时候的代码有所不同。首先是我原来的写法:
for(int i=n;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
a[i][n+1] -= a[j][n+1]*a[i][j];
}
下面这个是第一篇题解中的写法:
for(int i=n;i>=1;i--)
{
if(a[i][i] == 0) continue;
for(int j=i-1;j>=1;j--)
a[j][n+1] -= a[j][i]*a[i][n+1], a[j][i] = 0;
}
换成这样就 AC 了。
我的几次提交精度都是设置为 eps = 1e-16
,所以应该可以排除是精度上出了问题。
这几种写法感觉是等价的,为什么会前两次会出现各种各样的错误?
望大佬解答 /kel
by ducati @ 2020-08-10 20:14:19
本蒟蒻看看
by ducati @ 2020-08-10 20:22:31
我太菜了看不出问题,如果有人找出了问题可不可以@我一下
by Rusalka @ 2020-08-10 20:25:45
啊那个。。。计算主对角线时,我原先的代码是有判断 if(a[i][i] == 0) continue;
的,和这个没有关系
by Rusalka @ 2020-08-10 20:26:50
@ducati 好的
by ducati @ 2020-08-10 21:40:40
抛个代码, 如果您加入了代码公开计划应该就能看到吧
@ifndef