1.解线性方程组:
首先是n*n的矩阵,最终变成一个上三角的形式。
唯一解:完美的三角形。
0=非0,无解。
许多0=0,无穷解。
具体过程:
1.枚举每一列,找到绝对值最大的一行
2.将该行换到最上面。
3.将该行第一个数变成1.
4.将下面的第一个数变成0.
5.迭代(n-1)*(n-1)的问题。
6.求解,最后一个数系数变成1,得到xn的解。
对于上一行,用xn把它xn-1列的xn消掉得到xn-1,依次类推。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n;
double a[N][N];
double eps=1e-6;
int gas()
{
int c,r;
for(c=0,r=0;c<n;c++)
{
int t=r;
//找绝对值最大的行
for(int i=r;i<n;i++){
if(fabs(a[i][c])>fabs(a[t][c])) t=i;
}
//若为0
if(fabs(a[t][c])<eps) continue;//已经是0了没有必要继续
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);//交换
for(int i=n;i>=c;i--) a[r][i]/=a[r][c];//系数变成1
for(int i=r+1;i<n;i++)
{
if(fabs(a[i][c])>eps)
{
for(int j=n;j>=c;j--){
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()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
cin>>a[i][j];
}
}
int t=gas();
if(t==0)
{
for(int i=0;i<n;i++)
{
if (fabs(a[i][n]) < eps) a[i][n] = 0;
printf("%.2lf\n",a[i][n]);}
}
else if(t==1) cout<<"endless";
else cout<<"No Solution";
}
2.异或线性方程组
我们可以把异或看成不进位的加法:
由异或的交换与结合规则,我们考虑一下3种基本变换,首先系数0/1,于是不用乘倍数,显然交换两行的位置不影响,我们考虑下原本相减的情况,我们用异或那一行来替换,这样子就是对应原来减的操作了。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n;
int a[N][N];
int gas()
{
int c,r;
for(c=0,r=0;c<n;c++)
{
int t=r;
//找绝对值最大的行
for(int i=r;i<n;i++){
if(a[i][c])
{
t=i;
break;
}
}
//若为0
if(!a[t][c]) continue;//已经是0了没有必要继续
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);//交换
for(int i=r+1;i<n;i++)
{
if(a[i][c])
{
for(int j=n;j>=c;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];
}
}
return 0;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
cin>>a[i][j];
}
}
int t=gas();
if(t==0)
{
for(int i=0;i<n;i++) cout<<a[i][n]<<endl;
}
else if(t==1) cout<<"Multiple sets of solutions";
else cout<<"No solution";
}