Guass消元

约旦·高斯消元法 求线性方程组

我们用一个\(n*(n+1)\)的矩阵存储线性方程组各项系数和零次项系数。

  1. 每一次找到一个未知数系数最大的方程,交换当前行方程和该方程,并将其他行该未知数的系数化为零。
  2. 重复n次即可。
  3. 最后第\(a[i][i]\)个数就是第i个未知数的系数,\(a[i][n+1]\)是等式右侧的数,用后者除以前者即可。
  • 当化第i个方程时,若找到所有方程的最大值为零,即都为零,则无解。
  • 当一个未知数在多于0个少于n个方程中有系数,该未知数为自由元,线性方程组有无数组解。

洛谷P3389

#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;
}

让我们再做一道不那么板子的题目:

P4035 球形空间产生器

简述题意,我们需要求一个n维向量\((x_1,x_2,\dots,x_n)\)使得对于每个i都满足\(\sum_{j=1}^{n}(a_{i,j}-x_j)^2=dis\),

其中\(dis\)为未知常数。

所以我们考虑消去这个\(dis\):

我们将相邻的i的方程做差得到:

\[\sum_{j=1}^{n}a_{i+1,j}^2-a_{i,j}^{2}-2x_j(a_{i+1,j}-a_{i,j})=0
\]

然后将常数项与未知数剥离:

\[\sum_{j=1}^{n}2x_j(a_{a+1,j}-a_{i,j})=\sum_{j=1}^na_{i+1,j}^2-a_{i,j}^2
\]

解线性方程组即可。

题目给定有解。

#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大佬的课,我们可以知道矩阵求逆有一个方法是:

  1. 给原矩阵右边接一个等大的单位矩阵。
  2. 高斯消元,将原矩阵转为单位矩阵。
  3. 右侧矩阵即为所求。
#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;
}

Guass消元总结的更多相关文章

  1. UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  2. BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)

    BZOJ 3270 :设置状态为Id(x,y)表示一人在x,一人在y这个状态的概率. 所以总共有n^2种状态. p[i]表示留在该点的概率,Out[i]=(1-p[i])/Degree[i]表示离开该 ...

  3. hdu 5833 Zhu and 772002 高斯消元

    Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...

  4. hdu4418(概率dp + 高斯消元)

    应该是一个入门级别的题目. 但是有几个坑点. 1. 只选择x能到达的点作为guass中的未知数. 2. m可能大于n,所以在构建方程组时未知数的系数不能直接等于,要+= 3.题意貌似说的有问题,D为- ...

  5. hdu 5755(高斯消元——模线性方程组模板)

    PS. 看了大神的题解,发现确实可以用m个未知数的高斯消元做.因为确定了第一行的情况,之后所有行的情况都可以根据第一行推. 这样复杂度直接变成O(m*m*m) 知道了是高斯消元后,其实只要稍加处理,就 ...

  6. 【高斯消元】BZOJ 1770: [Usaco2009 Nov]lights 燈

    Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...

  7. 【高斯消元】Poj 1222:EXTENDED LIGHTS OUT

    Description In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each ...

  8. 【高斯消元】BZOJ 1013: [JSOI2008]球形空间产生器sphere

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁 ...

  9. ZJUT 1423 地下迷宫(期望DP&高斯消元)

    地下迷宫 Time Limit:1000MS  Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...

随机推荐

  1. Docker开启安全的TLS远程连接

    目录 1.1 不安全的远程访问方式 1.1.1 编辑docker.service文件: 1.1.2 重新加载Docker配置生效 1.1.3 警告! 2.1 建立基于TLS数字签名的安全连接 1.1 ...

  2. ORA-00937: not a single-group group function

    有时候查询会遇到如下错误   SCOTT@PROD> select deptno,sum(sal) from emp; select deptno,sum(sal) from emp       ...

  3. jenkins在aws eks中的CI/CD及slave

    本文档不讲解jenkins的基础用法,主要讲解配合k8s的插件,和pipeline的用途和k8s ci/cd的流程. 以及部署在k8s集群内和集群外的注意事项. 1.准备工作 以下在整个CI/CD流程 ...

  4. vsftpd.conf配置文件详解

    1.默认配置: 1>允许匿名用户和本地用户登陆. anonymous_enable=YES local_enable=YES 2>匿名用户使用的登陆名为ftp或anonymous,口令为空 ...

  5. 手把手教会你远程Linux虚拟机连接以及配置pytorch环境。

    出一期用于连接远程Ubuntu系统并配置pytorch环境的教学.2021-07-07 13:35:57- 现在的矿难导致显卡大幅度的涨价对很多要做深度学习领域的小伙伴们非常的不友好,配置设备固然要掏 ...

  6. 10 年 bloger 告诉你要不要写博客,又该如何优雅地写博客?

    关于作者:程序猿石头(ID: tangleithu),现任阿里巴巴技术专家,清华学渣,前大疆后端 Leader.公众号后台回复关键字 "1024" 获取程序员大厂面试指南. 图:D ...

  7. centos 8 安装 PostgreSQL-10

    下载 PostgreSQL-10软件包 官网地址:https://www.postgresql.org/ 选择自己的版本 此处已postgresql-10.16-2-linux-x64.run安装为例 ...

  8. MySQL参数配置

    参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名(用于连接数据库) 所有版本 passWord 用户密码(用于连接数据库) 所有版本 useUnicode 是否使用Unicode字符集 ...

  9. JDBC:Connection.close()

    https://www.2cto.com/database/201501/369246.html Connection对象在执行close() 方法之后,并不是直接把Connection对象设置为nu ...

  10. ubuntu16.04上编译android的可执行文件并调用本地so库

    前言: 找了蛮多资料的,发现目前实现的编译方式大致就两种,一种是直接使用android源码中的编译工具链,另一种就是使用独立的交叉编译工具链,第二种我还在实现中,配置步骤挺多的 ,第一种实现方式挺方便 ...