高斯消元

高斯消元 O(n^3)
求解有n个未知数、n个方程的方程组

 高斯消元的步骤:

        首先将方程左侧的系数和右侧的常数看作一个矩阵
      1.将这个矩阵变换为上三角形式
                某次遍历从第c列,第r行开始 
                ①找到第c列中绝对值最大的一行,换到第r行
                ②将这行中 第c列的数化为1 (该行的数倒序除这个数) 
                ③将第r行后,第c列的数都消为0 (每一行从右往左倒序更新)
        2.判断解的情况
        3.倒序求出未知数的解 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+5;
const double eps=1e-8;
int n;
double a[N][N];
// 将方程左侧的系数和右侧的常数看作一个矩阵
//  1.将这个矩阵变换为上三角形式
//	 某次遍历从第c列,第r行开始 
//	①找到第c列中绝对值最大的一行,换到第r行
//	②将这行中 第c列的数化为1 (该行的数倒序除这个数) 
//	③将第r行后,第c列的数都消为0
//	2.判断解的情况
//  3.倒序求出未知数的解 
int gauss(){
	//某次遍历从第c列,第r行开始 
	int c,r;
	for(c=0,r=0;c<n;c++){
		//找到在第c列中,第r行往后中绝对值最大的一行 
		int t=r;
		for(int i=r;i<n;i++){
			if(fabs(a[i][c])>fabs(a[t][c])){
				t=i;
			}
		}
		//如果这一列全为0就不处理 
		if(fabs(a[t][c])<eps) continue;
		//将这一行换到第r行 
		for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);
		//将这行中,第c列的数化为1 (即该行的数倒序除这个数) 
		for(int i=n;i>=c;i--) a[r][i]/=a[r][c];
		//将第r行往后,第c列的数都消成0
		for(int i=r+1;i<n;i++){
			if(fabs(a[i][c])<eps) continue;//已经为0 
			//此时a[r][c]==1 
			//倒序更新 
			for(int j=n;j>=c;j--){
				a[i][j]-=a[r][j]*a[i][c];
			} 
		} 
		r++;
	}

	//r<n说明有行没有被处理,出现无解或无穷解 
	//如果剩余的行 存在0==非零 则为无解
	//否则说明 存在0==0 则为无穷解 
	if(r<n){
		for(int i=r;i<n;i++){
			//存在0==非零,无解  
			if(fabs(a[i][n])>eps)
				return 2;
			//存在0==0,无穷解
		}
		return 1; 
	}
	//有唯一解
	//从最后一行倒着开始求未知数 
	//答案存于a[i][n]中
	for(int i=n-1;i>=0;i--){
		for(int j=i+1;j<n;j++){
			a[i][n]-=a[i][j]*a[j][n];
		}
	}
	return 0;
}
int main(){
	scanf("%d", &n);
	for(int i=0;i<n;i++){
		for(int j=0;j<n+1;j++){
			scanf("%lf",&a[i][j]);
		}
	}
	int t=gauss();
	if(t==0){
		for(int i=0;i<n;i++){
			if(fabs(a[i][n])<eps) a[i][n]=0;  // 去掉输出 -0.00 的情况
			printf("%.2lf\n",a[i][n]);
		} 
    }
    else if(t==1) puts("Infinite group solutions");
    else puts("No solution");


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vic.GoodLuck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值