用途:求线性方程组的解
解的个数
- 完美阶梯型——唯一解
- 0=非零——无解
- 存在0=0——无穷多解
时间复杂度:
步骤:
模板:
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
const double eps=1e-6;
int n;
double a[maxn][maxn];
int gauss(){
//枚举列
int r,c;
for(r=1,c=1;c<=n;c++){
//找主元
int id=r;
for(int i=r;i<=n;i++){
if(fabs(a[i][c])>fabs(a[id][c])){
id=i;
}
}
if(fabs(a[id][c])<eps)
continue;
//交换
for(int i=c;i<=n+1;i++){
swap(a[r][i],a[id][i]);
}
//归一
for(int i=n+1;i>=c;i--){
a[r][i]/=a[r][c];
}
//消
for(int i=r+1;i<=n;i++){
if(fabs(a[i][c])>eps){
for(int j=n+1;j>=c;j--){
a[i][j]-=a[r][j]*a[i][c];
}
}
}
r++;
}
//判断解的个数
if(r<=n){
return 1;
}
//按列消成对角矩阵
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
a[i][n+1]-=a[i][j]*a[j][n+1];
}
}
return 0;
}
int main(){
// freopen("123.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
scanf("%lf",&a[i][j]);
}
}
int t=gauss();
if(t==0){
for (int i = 1; i <= n; i ++ ){
if (fabs(a[i][n]) < eps) a[i][n] = 0;
printf("%.2lf\n", a[i][n+1]);
}
}
else{
puts("No Solution");
}
return 0;
}
应用一:
思路:此题只加了对解的个数的判断
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
const double eps=1e-6;
int n;
double a[maxn][maxn];
int gauss(){
//枚举列
int r,c;
for(r=1,c=1;c<=n;c++){
//找主元
int id=r;
for(int i=r;i<=n;i++){
if(fabs(a[i][c])>fabs(a[id][c])){
id=i;
}
}
if(fabs(a[id][c])<eps)
continue;
//交换
for(int i=c;i<=n+1;i++){
swap(a[r][i],a[id][i]);
}
//归一
for(int i=n+1;i>=c;i--){
a[r][i]/=a[r][c];
}
//消
for(int i=r+1;i<=n;i++){
if(fabs(a[i][c])>eps){
for(int j=n+1;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+1])>eps){
return 2;
}
return 1;
}
}
//按行消成对角矩阵
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
a[i][n+1]-=a[i][j]*a[j][n+1];
}
}
return 0;
}
int main(){
// freopen("123.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
scanf("%lf",&a[i][j]);
}
}
int t = gauss();
if (t == 0)
{
for (int i = 1; i <= n; i ++ ){
if (fabs(a[i][n+1]) < eps) a[i][n+1] = 0;
printf("%.2lf\n", a[i][n+1]);
}
}
else if (t == 1) puts("Infinite group solutions");
else puts("No solution");
return 0;
}
应用二:
思路:异或<=>不进位的加法
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
int n,a[maxn][maxn];
int gauss(){
//枚举列
int r,c;
for(r=1,c=1;c<=n;c++){
//找主元
int id=r;
for(int i=r;i<=n;i++){
if(a[i][c]){
id=i;
break;
}
}
if(!a[id][c])
continue;
//交换
for(int i=c;i<=n+1;i++){
swap(a[r][i],a[id][i]);
}
//消
for(int i=r+1;i<=n;i++){
if(a[i][c]){
for(int j=n+1;j>=c;j--){
a[i][j]^=a[r][j];
}
}
}
r++;
}
//判断解的个数
if(r<=n){
for(int i=r;i<=n;i++){
if(a[i][n+1])
return 2;
}
return 1;
}
//按行消成对角矩阵
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
a[i][n+1]^=a[i][j]&a[j][n+1];
}
}
return 0;
}
int main(){
// freopen("123.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
scanf("%d",&a[i][j]);
}
}
int op=gauss();
if(op==0){
for(int i=1;i<=n;i++){
printf("%d\n",a[i][n+1]);
}
}
else if(op==1) printf("Multiple sets of solutions\n");
else printf("No solution\n");
return 0;
}
应用三:
思路:
code: