高斯消元模版
时间:2022-05-07
本文章向大家介绍高斯消元模版,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
这模版敲了我俩个小时+写注释,参考自kuangbin!
两百行的大模拟,累死了QAQ
下面附上模版!
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn=50;
4 typedef long long ll;
5 int a[maxn][maxn];///增广矩阵
6 int x[maxn];///解集
7 bool free_x[maxn];///标记是否是不确定的变元
8 /*
9 void debug(void)
10 {
11 int i,j;
12 for(i=0;i<equ;i++)
13 {
14 for(j=0;j<var+1;j++)
15 {
16 cout<<a[i][j]<<" ";
17 }
18 cout<<endl;
19 }
20 cout<<endl;
21 }
22 */
23 inline int read()
24 {
25 int x=0,f=1;
26 char ch=getchar();
27 while(ch<'0'||ch>'9')
28 {
29 if(ch=='-')
30 f=-1;
31 ch=getchar();
32 }
33 while(ch>='0'&&ch<='9')
34 {
35 x=x*10+ch-'0';
36 ch=getchar();
37 }
38 return x*f;
39 }
40 inline void write(int x)
41 {
42 if(x<0)
43 {
44 putchar('-');
45 x=-x;
46 }
47 if(x>9)
48 write(x/10);
49 putchar(x%10+'0');
50 }
51 inline int gcd(int a,int b)///最大公约数
52 {
53 return b==0?a:gcd(b,a%b);
54 }
55 inline int lcm(int a,int b)///最小公倍数
56 {
57 return a/gcd(a,b)*b;///先除后乘防溢出
58 }
59 ///高斯消元法解方程组【-2表示有浮点型解,无整数解】
60 ///【-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由元的个数】
61 ///【有equ方程,var个变元,增广矩阵行数为equ,分别为0->equ-1,列数为var+1,分别为0->var】
62 int Gauss(int equ,int var)
63 {
64 int i,j,k;
65 int max_r;///当前这列绝对值最大的行
66 int col;///当前处理的列
67 int ta,tb;
68 int LCM;
69 int temp;
70 int free_x_num;
71 int free_index;
72 for(i=0;i<=var;i++)
73 {
74 x[i]=0;
75 free_x[i]=true;
76 }
77 ///转化为阶梯型矩阵
78 col=0;///处理当前列
79 for(k=0;k<equ&&col<var;k++,col++)///枚举当前处理的行
80 {
81 ///找到该col列元素绝对值最大的那一行与第k行交换(为了在除法时减小误差)
82 max_r=k;
83 for(i=k+1;i<equ;i++)
84 {
85 if(abs(a[i][col])>abs(a[max_r][col]))
86 max_r=i;
87 }
88 if(max_r!=k)
89 {
90 ///与第k行交换
91 for(j=k;j<var+1;j++)
92 {
93 swap(a[k][j],a[max_r][j]);
94 }
95 }
96 if(a[k][col]==0)
97 {
98 ///说明该col列第k行以下全是0了,则处理当前行的下一列
99 k--;
100 continue;
101 }
102 for(i=k+1;i<equ;i++)
103 {
104 ///枚举要删除的行
105 if(a[i][col]!=0)
106 {
107 LCM=lcm(abs(a[i][col]),abs(a[k][col]));
108 ta=LCM/abs(a[i][col]);
109 tb=LCM/abs(a[k][col]);
110 if(a[i][col]*a[k][col]<0)
111 tb=-tb;///异号情况是相加
112 for(j=col;j<var+1;j++)
113 {
114 a[i][j]=a[i][j]*ta-a[k][j]*tb;
115 }
116 }
117 }
118 }
119 ///debug();
120 ///无解的情况:化简的增广矩阵中存在(0,0,......a)这样的行(a!=0)
121 for(i=k;i<equ;i++)
122 {
123 if(a[i][col]!=0)
124 return -1;
125 }
126 ///对于无穷解来说,如果要判断哪些是自由元,那么初等变换中的交换就会影响,则要记录交换
127 ///无穷解的情况:在var*(var+1)的增广矩阵中,出现(0,0,......0)这样的行,即说明没有形成严格的上三角阵
128 ///且目前出现的行数即为自由元的个数
129 if(k<var)
130 {
131 ///首先,自由元有var-k个,即不确定的变元至少有var-k个
132 for(i=k-1;i>=0;i--)
133 {
134 ///第i行一定不会是(0,0,......0)的情况,因为这样的行是在第k行到第equ行
135 ///同样,第i行一定不会是(0,0,......a),(a!=0)这样的情况无解
136 free_x_num=0;///用于判断该行中的不确定的变元的个数,如果超过1就无法求解它们仍为不确定的变元
137 for(j=0;j<var;j++)
138 {
139 if(a[i][j]!=0&&free_x[j]!=0)
140 {
141 free_x_num++;
142 free_index=j;
143 }
144 }
145 if(free_x_num>1)
146 continue;///无法求出确定的变元
147 ///说明只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的,
148 temp=a[i][var];
149 for(j=0;j<var;j++)
150 {
151 if(a[i][j]!=0&&j!=free_index)
152 temp-=a[i][j]*x[j];
153 }
154 x[free_index]=temp/a[i][free_index];///求出该变元
155 free_x[free_index]=0;///该变元是确定的
156 }
157 return var-k;
158 }
159 ///唯一解的情况:在var*(var+1)的增广矩阵中形成严格的上三角形
160 ///求出Xn-1,Xn-2,......X0
161 for(i=var-1;i>=0;i--)
162 {
163 temp=a[i][var];
164 for(j=i+1;j<var;j++)
165 {
166 if(a[i][j]!=0)
167 temp-=a[i][j]*x[j];
168 }
169 if(temp%a[i][i]!=0)
170 return -2;///说明有浮点数解,但无整数解
171 x[i]=temp/a[i][i];
172 }
173 return 0;
174 }
175 int main(void)
176 {
177 ///freopen("in.txt","r",stdin);
178 ///freopen("out.txt","w",stdout);
179 int i,j;
180 int equ,var;
181 while(equ=read(),var=read())
182 {
183 memset(a,0,sizeof(a));
184 for(i=0;i<equ;i++)
185 {
186 for(j=0;j<var+1;j++)
187 {
188 a[i][j]=read();
189 }
190 }
191 ///debug();
192 int free_num=Gauss(equ,var);
193 if(free_num==-1)
194 printf("No solutionn");///无解
195 else if(free_num==-2)
196 printf("There are floating point numbers, no integer solutionsn");///有浮点数解,无整数解
197 else if(free_num>0)
198 {
199 printf("The number of variables of infinite solution is:%dn",free_num);///无穷多解,自由变元个数为
200 for(i=0;i<var;i++)
201 {
202 if(free_x[i]!=0)
203 printf("x%d is not suren",i+1);
204 else
205 printf("x%d:%dn",i+1,x[i]);
206 }
207 }
208 else
209 {
210 for(i=0;i<var;i++)
211 printf("x%d:%dn",i+1,x[i]);
212 }
213 printf("n");
214 }
215 return 0;
216 }
- SQL SERVER 2008 Hierarchyid数据类型
- Html5 学习利器 Web Standards Update for Microsoft Visual Studio 2010 SP1
- MongoDB 客户端 MongoVue
- HttpClient介绍
- 10个使用 Foundation 框架开发的WordPress 主题推荐
- jQuery 效果使用
- 几款更换WordPress 后台UI 的插件推荐
- 入门:构建简单的Web API
- WordPress 编辑器快捷键——让写作来得更方便些吧!
- ASP.NET Web API: 宿主(Hosting)
- 在 Windows Phone上使用QQConnect OAuth2
- WordPress 开发之使用WordPress 3.8+后台图标(dashicons)
- 基础(二)
- Ionic:高级的 HTML5 移动APP(Web App)开发框架
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring Boot入门系列(十九)集成mybatis
- 当我们做后仿时我们究竟在仿些什么(四)
- Scala学习一
- kafka学习二 -发送消息
- 【ACL2020】使用问题图生成解决multi-hop复杂KBQA
- R语言实现DNA结构预测
- Vue 基础入门
- Chrome DevTools 一些隐藏技巧
- Leetcode 1160. 拼写单词 (Hash)
- CodeForces 23B (图论 思维)
- JDBC 进阶操作
- Leetcode 面试题 01.06. 字符串压缩 (字符串模拟)
- Centos 7 安装 Git
- 受限平均生存时间(Restricted mean survival time)简析及R语言实现
- Leetcode 695. 岛屿的最大面积 (DFS)