Guass消元总结
Guass消元
约旦·高斯消元法 求线性方程组
我们用一个的矩阵存储线性方程组各项系数和零次项系数。
- 每一次找到一个未知数系数最大的方程,交换当前行方程和该方程,并将其他行该未知数的系数化为零。
- 重复n次即可。
- 最后第个数就是第i个未知数的系数,是等式右侧的数,用后者除以前者即可。
- 当化第i个方程时,若找到所有方程的最大值为零,即都为零,则无解。
- 当一个未知数在多于0个少于n个方程中有系数,该未知数为自由元,线性方程组有无数组解。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cmath>
using namespace std;
inline int read(){
int x=0,w=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=105;
double a[maxn][maxn];
int n;
inline void work(){
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)a[i][j]=(double)read();
for(int i=1;i<=n;i++){
int mx=i;
for(int j=i+1;j<=n;j++)
if(fabs(a[j][i])>fabs(a[mx][i]))mx=j;
swap(a[i],a[mx]);
if(!a[i][i])return (void)puts("No Solution");
for(int j=1;j<=n;j++){
if(j==i)continue;
double tmp=a[j][i]/a[i][i];
for(int k=i+1;k<=n+1;k++)
a[j][k]-=a[i][k]*tmp;
}
}
for(int i=1;i<=n;i++)printf("%.2lf\n",a[i][n+1]/a[i][i]);
}
}
signed main(){
star::work();
return 0;
}
让我们再做一道不那么板子的题目:
简述题意,我们需要求一个n维向量使得对于每个i都满足,
其中为未知常数。
所以我们考虑消去这个:
我们将相邻的i的方程做差得到:
然后将常数项与未知数剥离:
解线性方程组即可。
题目给定有解。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cmath>
using namespace std;
const int maxn=12;
double b[maxn][maxn],a[maxn][maxn];
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n;j++)scanf("%lf",&b[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=(b[i][j]-b[i+1][j])*2;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
a[i][n+1]+=b[i][j]*b[i][j]-b[i+1][j]*b[i+1][j];
}
for(int i=1;i<=n;i++){
int mx=i;
for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>fabs(a[mx][i]))mx=j;
swap(a[mx],a[i]);
for(int j=1;j<=n;j++){
if(j==i)continue;
double tmp=a[j][i]/a[i][i];
for(int k=i+1;k<=n+1;k++)
a[j][k]-=a[i][k]*tmp;
}
}
for(int i=1;i<=n;i++)printf("%.3lf ",a[i][n+1]/a[i][i]);
return 0;
}
求行列式的值
依据行列式的性质,我们用高斯消元将行列式转变为下三角矩阵,行列式的值就为对角线上各数的积。
- 当行列式其中两行成比例时行列式值为零。所以我们在高斯消元的时候发现只要有一列找不到有值的数就是这种情况,直接返回0即可。
- 一般来说,求行列式有可能加模数或者行列式值很大,我们在除的时候用逆元搞就行了。
inline int Guass(int *a){
int ans=1;
for(int i=1;i<=n;i++){
int pos=0;
for(int j=i;j<=n;j++)if(a[j][i]){pos=j;break;}
if(!pos)return 0;
if(pos!=i)swap(a[pos],a[i]);
int inv=fpow(a[i][i],mod-2,mod);//快速幂
for(int j=i+1;j<=n;j++){
if(a[j][i]){
ans=ans*inv%mod;
for(int k=i+1;k<=n;k++)
a[j][k]=((a[j][k]*a[i][i]%mod-a[i][k]*a[j][i]%mod)%mod+mod)%mod;
a[j][i]=0;
}
}
}
for(int i=1;i<=n;i++)ans=ans*a[i][i]%mod;
return ans;
}
求逆矩阵
根据rsk大佬的课,我们可以知道矩阵求逆有一个方法是:
- 给原矩阵右边接一个等大的单位矩阵。
- 高斯消元,将原矩阵转为单位矩阵。
- 右侧矩阵即为所求。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cmath>
#define int long long
using namespace std;
inline int read(){
int x=0,w=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=405,mod=1e9+7;
int n,a[maxn][maxn<<1];
inline int fpow(int a,int b){
int ans=1;
for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
return ans;
}
inline void work(){
n=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)a[i][j]=read();
a[i][n+i]=1;
}
for(int i=1;i<=n;i++){
int mx=i;
for(int j=i+1;j<=n;j++)
if(a[mx][i]<a[j][i])mx=j;
swap(a[mx],a[i]);
if(!a[i][i])return (void)puts("No Solution");
int inv=fpow(a[i][i],mod-2);
for(int j=1;j<=n;j++){
if(j==i)continue;
for(int tmp=a[j][i]*inv%mod,k=1;k<=n*2;k++)//k可以从i+1开始,不会更新下三角
a[j][k]=(a[j][k]-a[i][k]*tmp%mod+mod)%mod;
}
}
for(int i=1;i<=n;i++){
for(int tmp=fpow(a[i][i],mod-2),j=1;j<=n;j++)
printf("%lld ",a[i][j+n]*tmp%mod);
puts("");
}
}
}
signed main(){
star::work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现