普通高斯消元
枚举每一列c,
找到当前列绝对值最大的一行
将该行换到当前最上面
将该行的第一个数变成 1,其余所有的数字依次跟着变化
将下面所有行的这一列的值变成 0,其余数字也要跟着变化
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
const double eps=1e-6;
int n;
double a[N][N];
int guass()
{
int c,r;
for(c=0,r=0;c<n;c++)
{
int t=r;
for(int i=r;i<n;i++)//找到r-n行中第c列绝对值最大的行
if(fabs(a[i][c])>fabs(a[t][c]))
t=i;
if(fabs(a[t][c])<eps) continue;//如果r-n行中的第c列的值都为0,则跳过
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);//交换第t行和第r行
for(int i=n;i>=c;i--) a[r][i]/=a[r][c];//将a[r][c]的值变为 1,i要从n开始,不能从c开始,否则会出错
for(int i=r+1;i<n;i++)//将r+1-n行的第c列上的值变为0
{
if(fabs(a[i][c])>eps)
for(int j=n;j>=c;j--)//i要从n开始,不能从c开始,否则会出错
a[i][j]-=a[r][j]*a[i][c];
}
r++;
}
if(r<n)
{
for(int i=r;i<n;i++)
if(fabs(a[i][n])>eps) return 2;//无解
return 1;//有无穷多组解
}
for(int i=n-1;i>=0;i--)
for(int j=i+1;j<=n;j++)
a[i][n]-=a[i][j]*a[j][n];
return 0;//有唯一解
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%lf",&a[i][j]);
int t=guass();
if(t==2) printf("No solution") ;
else if(t==1) printf("Infinite group solutions");
else
for(int i=0;i<n;i++)
printf("%.2f\n",a[i][n]);
return 0;
}
异或高斯消元
枚举每一列c,
找到当前列中值为1的行
将该行换到当前最上面
将下面所有行的这一列的值变成 0,其余数字也要跟着变化
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n;
int a[110][110];
int guass()
{
int r,c;
for(r=0,c=0;c<n;c++)
{
int t=r;
for(int i=r;i<n;i++)//在r-n行中选择第c列上为1的行
if(a[i][c])
{
t=i;
break;
}
if(!a[t][c]) continue;//如果都为0,则跳过
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);//交换第t行和第r行
for(int i=r+1;i<n;i++)
if(a[i][c])//如果 r+1-n行中第c列上的值为1,则将其变为0
for(int j=c;j<=n;j++)
a[i][j]^=a[r][j];
r++;
}
if(r<n)
{
for(int i=r;i<n;i++)
if(a[i][n]) return 2;//无解
return 1;//有多组解
}
for(int i=n-1;i>=0;i--)//有唯一解
for(int j=i+1;j<n;j++)
a[i][n]^=a[i][j]&a[j][n];
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%d",&a[i][j]);
int t=guass();
if(t==2) printf("No solution");
else if(t==1) printf("Multiple sets of solutions");
else
for(int i=0;i<n;i++)
printf("%d\n",a[i][n]);
return 0;
}