Mine_King @ 2022-08-20 15:50:09
我记得若干年前我看到某篇文章说高斯-约旦消元法无法区分无解和无穷解,但是现在我 hack 不来,有没有大佬教教/kel
by _HMZ_ @ 2022-08-20 16:15:35
我认为的判断方法是这样的。
正常消元判断无解/多解是当第i列全为0,此时无法确定第i个的值。
但我们可以在第i列全为0的时候跳过,去消i+1,此时会出现这样的矩阵。
10000 112233
01000 355640
00000 0
00010 123
00001 123123123
即中间出现了断层的情况,那么如果断层那一行的b不是0,就代表0 a[1]+0 a[2]+0 * a[3]……!=0,明显无解。
否则这一行是0,代表这个数无论怎么选都不会影响答案,就是多解
by _HMZ_ @ 2022-08-20 16:16:05
@Mine_King
by 王熙文 @ 2023-08-03 20:29:45
@HMZ ?假飞了。你现在再交一下这题的代码,应该过不去了。
by _HMZ_ @ 2023-08-03 20:41:56
@王熙文 我过了啊/oh
by 王熙文 @ 2023-08-03 20:58:15
@HMZ ???发个代码
by _HMZ_ @ 2023-08-04 07:55:36
@王熙文
#include<iostream>
#include<cmath>
using namespace std;
int n,m;
double val[1005][1005];
void Guess()
{
int line=1;
for(int i=1;i<=n;i++)
{
double maxx=0;
int id=line;
for(int j=line;j<=n;j++)
if(fabs(val[j][i])>maxx)
maxx=fabs(val[j][i]),id=j;
if(maxx==0) continue;
if(id!=line)
for(int j=1;j<=n+1;j++)
swap(val[line][j],val[id][j]);
double tmp=val[line][i];
for(int j=i;j<=n+1;j++)
val[line][j]/=tmp;
for(int j=1;j<=n;j++)
{
if(j==line) continue;
double tmp=val[j][i];
for(int k=i;k<=n+1;k++)
val[j][k]-=tmp*val[line][k];
}
++line;
}
bool vis=(line!=n+1);
while(line<=n)
{
if(val[line][n+1]!=0)
{
cout<<-1;
exit(0);
}
++line;
}
if(vis) cout<<0;
else
for(int i=1;i<=n;i++)
printf("x%d=%.2lf\n",i,val[i][n+1]);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)
cin>>val[i][j];
Guess();
return 0;
}
/*
3
2 -1 0 2
4 1 0 4
1 1 0 1
*/
by 王熙文 @ 2023-08-04 08:13:44
@HMZ that's right, but i dont think your sample is right. in your sample, you skip a row and a column at the same time while your code dont skip row.(i dont know why my mobile cant send chinese)
by 王熙文 @ 2023-08-04 08:16:09
sorry to my poor english