• 高斯消元


    #include <cstdio>
    const int N=104;
    double a[N][N];
    int n;
    double fabs(double x) {return x>0?x:-x;}
    void swap(int i,int j)
    {
        double tmp;
        for(int k=i;k<=n+1;k++)
        {
            tmp=a[i][k];
            a[i][k]=a[j][k];
            a[j][k]=tmp;
        }
    }
    bool gauss()
    {
        for(int i=1;i<=n;i++)//枚举每一行
        {
            double m_max=0.0;
            int id;
            for(int j=i;j<=n;j++)//找到最大的当前系数,减小精度误差
                if(m_max<fabs(a[j][i]))
                {
                    m_max=fabs(a[j][i]);
                    id=j;
                }
            if(m_max<1e-8)//判断是否存在唯一解
                return false;
            swap(i,id);//交换到最大系数
            //下面的代码尽可能的减小了常数并提高了精度
            double now=a[i][i];
            for(int j=i;j<=n+1;j++)//将首项除成1,也是唯一的除法运算
                a[i][j]/=now;
            for(int j=i+1;j<=n;j++)
            {
                now=a[j][i];//此时的now即为第i行要乘的系数(消i列)
                for(int k=i;k<=n+1;k++)
                    a[j][k]-=a[i][k]*now;//其他项的系数处理
            }
        }
        for(int i=n;i>=1;i--)
            for(int j=i-1;j>=1;j--)
            {
                a[j][n+1]-=a[i][n+1]*a[j][i];
    //用第i行已经出来的式子,为...0 0 0 1 0 0 0...a(右边常数)
    //对上面每一行的式子都搞一遍,消去这个未知数
                a[j][i]=0;
            }
        return true;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
                scanf("%lf",&a[i][j]);
        if(gauss())
        {
            for(int i=1;i<=n;i++)
                printf("%.2lf ",a[i][n+1]);
        }
        else
            printf("No Solution");
        return 0;
    }
    

    • 这是个死东西。

    • 注意精度问题常数优化

  • 相关阅读:
    第四次作业
    随机点名
    表单验证
    冒泡排序&&选择排序
    Equals相等
    String类
    最终类final
    Eclipse的设置
    Equals相等(测试)
    猜数字
  • 原文地址:https://www.cnblogs.com/butterflydew/p/8999766.html
Copyright © 2020-2023  润新知