zoukankan      html  css  js  c++  java
  • 高斯消元法

    题面

    Gauss消元

    题目描述

    给定一个线性方程组,对其求解
    输入输出格式

    输入格式:

    第一行,一个正整数n

    第二至n+1行,每行n+1个整数,为a1,a2...an和b,代表一组方程。

    输出格式:

    共n行,每行一个数,第i行为xi (保留2位小数)

    如果不存在唯一解,在第一行输出"No Solution".

    输入输出样例

    输入样例#1:

    1
    1 1

    输出样例#1:

    1.00

    说明

    1<=n<=100, |ai|<=10000, |b|<=10000

    题解

    高斯消元法,数学中比较常见的方法。

    通过构造矩阵来求解多元一次方程,其主要思想就是加减消元法。

    主要步骤如下(构成上三角):

    1.选定未被选择过的、xi项系数绝对值最大的一行(这样更加容易判断是否有解),将整个式子除以xi的系数(xi系数化为1)。同时将其交换至第i行(方便求解)

    2.将未被选择过的行中的该项全部按照系数相应的减去选定的那行的系数(剩下的其他行xi系数化为0)

    当所有行都选定过时,已经构成了上三角

    3.倒序求解,每次将常数减去已经求出的所有项的解,此时可以求出当前项的解(将已知解带入求未知解)

    最后依次输出即可

    源代码:

    无所谓读入优化了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAX 110
    using namespace std;
    double g[MAX][MAX];
    int n,now;
    inline void read(double &x)
    {
          x=0;
          short int t=1;
          char ch=getchar();
          while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
          if(ch=='-')
          {
                  t=-1;
                  ch=getchar();
          }
          while(ch>='0'&&ch<='9')
          {
                   x=x*10+ch-48;
                   ch=getchar();
          }
          x*=t;
    }
    int main()
    {
          cin>>n;
          for(int i=1;i<=n;++i)
                 for(int j=1;j<=n+1;++j)
                    read(g[i][j]);
          for(int i=1;i<=n;++i)
          {
                  now=i;
                  for(int j=i+1;j<=n;++j)//找出当前项系数的绝对值的最大值 
                    if(fabs(g[now][i])<fabs(g[j][i]))
                       now=j;
                  for(int j=i;j<=n+1;++j)//将其放在对应的行,方便计算 
                    swap(g[now][j],g[i][j]);
                  if(g[i][i]==0)//如果此时绝对值最大系数已经为0 
                  {             //则证明此方程组无解 
                          cout<<"No Solution"<<endl; 
                          return 0;
                  }
                for(int j=i+1;j<=n+1;++j)//将系数化为1 
                   g[i][j]/=g[i][i];
                g[i][i]=1;
                for(int j=i+1;j<=n;++j)//在其他式子中将此项系数化为0 
                {
                      for(int k=i+1;k<=n+1;++k)
                        g[j][k]-=g[j][i]*g[i][k];
                      g[j][i]=0;
                }
          }//做完之后,剩余的矩阵是上三角
          for(int i=n;i>=1;--i)//倒着求解即可 
          {
                  for(int j=i+1;j<=n;++j)//减去后面所有已经求出解的值 
                  {
                      g[i][n+1]-=g[i][j]*g[j][n+1];
                      g[i][j]=0;
                  }
                  g[i][n+1]/=g[i][i];   //只剩下当前的未知量以及常数量(其实没必要除,因为已经是1了) 
                  g[i][i]=1;
          }
          for(int i=1;i<=n;++i)
            printf("%.2f
    ",g[i][n+1]);
          return 0;
    }
    
  • 相关阅读:
    初拾Java(问题一:404错误,页面找不到)
    新年新气象--总结过去,展望未来
    接口测试[整理]
    [转]SVN-版本控制软件
    浅谈黑盒测试和白盒测试
    Bug管理工具的使用介绍(Bugger 2016)
    P2805/BZOJ1565 [NOI2009]植物大战僵尸
    近期学习目标
    P3643/BZOJ4584 [APIO2016]划艇
    P5344 【XR-1】逛森林
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7196259.html
Copyright © 2011-2022 走看看