有个疑问

P2455 [SDOI2006] 线性方程组

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 因为高斯消元的目的是让每行只留下一个变量和常数,而选取行主元意味着使选取的主元成为这一行最终要留下的变量


|