lupengheyyds @ 2024-05-29 09:47:22
为什么第一份代码 WA 了第3个点(无数解判成无解),但第二份代码AC了
by lupengheyyds @ 2024-05-29 09:47:41
第一份代码:
void Gauss_J(){
for(int i=1;i<=n;i++){
if(d[i][i]==0)for(int j=i+1;j<=n;j++)if(d[j][i]!=0){swap(d[i],d[j]);break;}
if(d[i][i]==0)for(int j=i-1;j>=1;j--)if(d[j][i]!=0){swap(d[i],d[j]);break;}
if(d[i][i]==0)continue;
for(int j=n+1;j>=i;j--)d[i][j]/=d[i][i];
for(int j=1;j<=n;j++)if(i!=j)for(int k=n+1;k>=i;k--)d[j][k]-=d[j][i]*d[i][k];
}
for(int i=1;i<=n;i++)
if(d[i][i]==0&&d[i][n+1]!=0){
cout<<-1;return;
}
for(int i=1;i<=n;i++){
if(d[i][i]==0&&d[i][n+1]==0){
cout<<0;return;
}
}
for(int i=1;i<=n;i++){
printf("x%d=%.2f\n",i,d[i][n+1]);
}
}
by lupengheyyds @ 2024-05-29 09:48:53
第二份代码:
void Gauss_J(){
for(int i=1;i<=n;i++){
int line=i;
for(int j=i+1;j<=n;j++)if(d[j][i]!=0){line=j;break;}
if(d[line][i]==0)for(int j=1;j<i;j++)if(d[j][i]!=0){line=j;break;}
if(d[line][i]==0)continue;
swap(d[i],d[line]);
for(int j=n+1;j>=i;j--)d[i][j]/=d[i][i];
for(int j=1;j<=n;j++)if(i!=j)for(int k=n+1;k>=i;k--)d[j][k]-=d[j][i]*d[i][k];
}
for(int i=1;i<=n;i++)
if(d[i][i]==0&&d[i][n+1]!=0){
cout<<-1;return;
}
for(int i=1;i<=n;i++){
if(d[i][i]==0&&d[i][n+1]==0){
cout<<0;return;
}
}
for(int i=1;i<=n;i++){
printf("x%d=%.2f\n",i,d[i][n+1]);
}
}
by haozexu @ 2024-05-29 09:52:53
https://www.luogu.com.cn/discuss/669432
by lupengheyyds @ 2024-05-29 09:54:38
过Hack了
by Fasterfaster @ 2024-05-29 10:16:52
第一份代码把选主元部分
if(d[j][i]!=0)
改为
if(d[j][i]!=0 && d[j][j] == 0)
就过了。
一行不能同时选成多个变量的主元。选一行之前要判断之前有没有选过同样的行。
至于第二个为什么能过应该是随机原因,理论上有数据能把两个都卡掉。
by lupengheyyds @ 2024-10-03 21:47:11
@M1ndeveloped 可为什么会将无数解判成无解呢?
by Fasterfaster @ 2024-10-04 14:51:54
@lupengheyyds 因为你消元消错了,无数解判成无解只是一种特例
by lupengheyyds @ 2024-10-04 15:25:20
@M1ndeveloped 可以请问一下为什么“一行不能同时选成多个变量的主元”吗?
by Fasterfaster @ 2024-10-04 22:06:36
@lupengheyyds 因为高斯消元的目的是让每行只留下一个变量和常数,而选取行主元意味着使选取的主元成为这一行最终要留下的变量