码迷,mamicode.com
首页 > 其他好文 > 详细

P3389 【模板】高斯消元法

时间:2018-09-21 15:22:23      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:www.   get   print   algorithm   nbsp   ++   最大   col   lov   

传送门

把所有方程放到一个二维数组里

样例的数组为[ 1,3,4,5 ]

      [ 1,4,7,3 ]

      [ 9,3,2,2 ]

考虑一个一个消元

拿一个方程出来,把未知数 x 的系数化成1

用加减消元消去其他方程的 x

然后再消下一个未知数

最后一个未知数消完后再把值往上一个方程代入

最后每个未知数都求出来了

如果消 x 的时候发现所有方程的 x 的系数都是 0

那么 x 可以取任何值,就是有多个解

判一下就好了

拿方程时优先拿系数大的可以减小误差(懒得不会证明)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-7;
double mp[107][107],ans[107];
int n;
inline void slove()
{
    for(int i=1;i<=n;i++)//消去第i位未知数
    {
        double mx=mp[i][i]; int pos=i;
        for(int j=i+1;j<=n;j++)//注意前面的方程用过了不能再用
            if(fabs(mx)<fabs(mp[i][j]))
                mx=mp[i][j],pos=j;
        swap(mp[i],mp[pos]);//找系数最大的方程

        if(fabs(mp[i][i])<eps)//判一下多解的情况
        {
            cout<<"No Solution";
            exit(0);
        }

        double div=mp[i][i];
        for(int j=i;j<=n+1;j++)
            mp[i][j]/=div;//把此方程未知数的系数化为1
        for(int j=i+1;j<=n;j++)
        {
            div=mp[j][i];
            for(int k=i;k<=n+1;k++)
                mp[j][k]-=mp[i][k]*div;//用加减消元消去其他方程的此未知数
        }
    }

    for(int i=n;i;i--)
    {
        ans[i]=mp[i][n+1];
        for(int j=i+1;j<=n;j++)
            ans[i]-=mp[i][j]*ans[j];//把后面的答案往前带
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            scanf("%lf",&mp[i][j]);
        scanf("%lf",&mp[i][n+1]);
    }

    slove();

    for(int i=1;i<=n;i++)
        printf("%.2lf\n",ans[i]);
    return 0;
}

 

P3389 【模板】高斯消元法

标签:www.   get   print   algorithm   nbsp   ++   最大   col   lov   

原文地址:https://www.cnblogs.com/LLTYYC/p/9686047.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!