Guass消元总结
Guass消元
约旦·高斯消元法 求线性方程组
我们用一个\(n*(n+1)\)的矩阵存储线性方程组各项系数和零次项系数。
- 每一次找到一个未知数系数最大的方程,交换当前行方程和该方程,并将其他行该未知数的系数化为零。
- 重复n次即可。
- 最后第\(a[i][i]\)个数就是第i个未知数的系数,\(a[i][n+1]\)是等式右侧的数,用后者除以前者即可。
- 当化第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维向量\((x_1,x_2,\dots,x_n)\)使得对于每个i都满足\(\sum_{j=1}^{n}(a_{i,j}-x_j)^2=dis\),
其中\(dis\)为未知常数。
所以我们考虑消去这个\(dis\):
我们将相邻的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;
}
Guass消元总结的更多相关文章
- 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 ...
- BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)
BZOJ 3270 :设置状态为Id(x,y)表示一人在x,一人在y这个状态的概率. 所以总共有n^2种状态. p[i]表示留在该点的概率,Out[i]=(1-p[i])/Degree[i]表示离开该 ...
- hdu 5833 Zhu and 772002 高斯消元
Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...
- hdu4418(概率dp + 高斯消元)
应该是一个入门级别的题目. 但是有几个坑点. 1. 只选择x能到达的点作为guass中的未知数. 2. m可能大于n,所以在构建方程组时未知数的系数不能直接等于,要+= 3.题意貌似说的有问题,D为- ...
- hdu 5755(高斯消元——模线性方程组模板)
PS. 看了大神的题解,发现确实可以用m个未知数的高斯消元做.因为确定了第一行的情况,之后所有行的情况都可以根据第一行推. 这样复杂度直接变成O(m*m*m) 知道了是高斯消元后,其实只要稍加处理,就 ...
- 【高斯消元】BZOJ 1770: [Usaco2009 Nov]lights 燈
Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...
- 【高斯消元】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 ...
- 【高斯消元】BZOJ 1013: [JSOI2008]球形空间产生器sphere
Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁 ...
- ZJUT 1423 地下迷宫(期望DP&高斯消元)
地下迷宫 Time Limit:1000MS Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...
随机推荐
- 用MAILX 发送邮件
使用 25 端口发送 mail 编辑/etc/mail.rc 文件,添加以下信息vi /etc/mail.rc set from=xxx@163.com smtp=smtp.163.comset sm ...
- 基于Android平台的图书管理系统的制作(4)
讲解完学生.职员.书籍这些基础层之后,我们可以来了解一些应用层的活动. 新书上架.借阅排行.黑名单.图书馆介绍.图书馆新闻. 新书上架是查询数据库里的Book表,将最近注册的五本书的基本信息(若图书馆 ...
- Docker开启安全的TLS远程连接
目录 1.1 不安全的远程访问方式 1.1.1 编辑docker.service文件: 1.1.2 重新加载Docker配置生效 1.1.3 警告! 2.1 建立基于TLS数字签名的安全连接 1.1 ...
- 【Azure 机器人】微软Azure Bot 编辑器系列(3) : 机器人对话流中加入帮助和取消按钮功能 (The Bot Framework Composer tutorials)
欢迎来到微软机器人编辑器使用教程,从这里开始,创建一个简单的机器人. 在该系列文章中,每一篇都将通过添加更多的功能来构建机器人.当完成教程中的全部内容后,你将成功的创建一个天气机器人(Weather ...
- MySQL 页完全指南——浅入深出页的原理
之前写了一些关于 MySQL 的 InnoDB 存储引擎的文章,里面好几次都提到了页(Pages)这个概念,但是都只是简要的提了一下.例如之前在聊 InnoDB内存结构 时提到过,但当时的重点是内存架 ...
- v-for和v-if不能同时使用
如果使用v-for遍历数据时,想筛选出URL不为空的项并进行渲染 <ul> <li v-for="(item,index) in list" v-if=" ...
- Pandas高级教程之:处理text数据
目录 简介 创建text的DF String 的方法 columns的String操作 分割和替换String String的连接 使用 .str来index extract extractall c ...
- 回顾Games101图形学(一)几何变换中一些公式的推导
回顾Games101 chatper1 - 6 前言 本文只写回顾后重新加深认识的知识 透视除法的意义 经过MVP矩阵之后,将模型空间下某点的坐标,转换成了裁剪空间下的坐标,此时因为裁剪空间的范围是x ...
- WEB安全新玩法 [5] 防范水平越权之查看他人订单信息
水平越权是指系统中的用户在未经授权的情况下,查看到另一个同级别用户所拥有的资源.水平越权会导致信息泄露,其产生原因是软件业务设计或编码上的缺陷.iFlow 业务安全加固平台可以缓解部分场景下的水平越权 ...
- 玩转html2canvas以及常见问题解决
前端小伙伴经常会遇到页面截图或者把网页中指定的区域(某个大div)的内容转换成png的图片.这个时候常常会用到html2canvas库来实现,js真的很强大. 我最近也遇到了一个需求,需要把输入的文本 ...