• 高斯消元简析


    想必大家都可以非常迅速的解出一个二元一次方程组,

    那么三元呢(这也还好),那么再多一些未知数?

    于是这里就要介绍到高斯消元的方法了...

    本人蒟蒻到现在才学高斯消元,请不要介意方法过于垃圾

     --------------------------------------------------------------------------------------------------

    首先假设你拿到了一个n元方程组,那么它应该有n个方程,每个方程有n+1个系数,

    好于是我们把他们全部弄到一个n*(n+1)的矩阵中,这里简称为系数矩阵

    第一步:我们先把每一行的系数都除以这一行的第一个数

    第二步:从第一行到第n行分别控制x1...xn的解,因此你需要把第i行的第i列的系数化为1以此来求解方程,

    第三步:在处理第i行的时候,把第i+1行到第n行的数通过加减消元法处理

       

    第四步:那么求出这个答案就是最后的答案数组了,

    求答案是xn的值是a[n][n+1],然后如果求x(n-1)的值就是将xn的值代入a[n-1][n],然后求出x(n-1)的值

    于是乎 x1=-1,x2=3,x3=-6

    以上就是关于高斯消元简要的介绍.

    下面是两种不同题目下的高斯消元

    (1) 方程保证是整数解,且系数大小均为long long 以内

    注意:此处运用到简单的高精度,以及取模

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define ll long long
     7 using namespace std;
     8 const ll p=1000000000000000009;
     9 ll a[210][210],ans[210];
    10 ll mul(ll a,ll b){return (__int128)a*b%p;}
    11 ll inv(ll a){
    12     ll res=1,b=p-2;
    13     while (b){
    14         if (b&1) res=mul(res,a); b>>=1; a=mul(a,a);
    15     } return res;
    16 }
    17 ll Div(ll a,ll b){return mul(a,inv(b));}
    18 ll read(){
    19     char ch[1010]; scanf("%s",ch+1);
    20     ll res=0,len=strlen(ch+1);
    21     for (int i=1;i<=len;++i){
    22         res=mul(res,10)+ch[i]-'0';
    23         if (res>p) res-=p;
    24     }
    25     return res;
    26 }
    27  
    28  
    29 int main() {
    30     int n;scanf("%d",&n);
    31     for(int i=1;i<=n;i++){
    32         for(int j=1;j<=n;j++)
    33             scanf("%lld",&a[i][j]);
    34         a[i][n+1]=read();
    35         ll res=a[i][1];
    36         for(int j=1;j<=n+1;j++) a[i][j]=Div(a[i][j],res);
    37     }
    38     for(int i=1;i<=n;i++){
    39         if (a[i][i]==0) {puts("zzylihai"); return 0;}
    40         for(int j=i+1;j<=n+1;++j)
    41             a[i][j]=Div(a[i][j],a[i][i]);
    42         a[i][i]=1;
    43         for(int j=i+1;j<=n;j++) {
    44             for(int k=i+1;k<=n+1;k++){
    45                 a[j][k]-=mul(a[j][i],a[i][k]);
    46                 if (a[j][k]<0) a[j][k]+=p;
    47             }
    48             a[j][i]=0;
    49         }
    50     }
    51     for(int i=n;i>=1;i--) {
    52         ll res=a[i][n+1];
    53         for(int j=i+1;j<=n;j++) {
    54             res-=mul(ans[j],a[i][j]);
    55             if (res<0) res+=p;
    56         }
    57         ans[i]=Div(res,a[i][i]);
    58     }
    59     for(int i=1;i<=n;i++) printf("%lld
    ",ans[i]);
    60     return 0;
    61 }
    View Code

    (2)方程为实数解,要判断是否无解

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    double a[210][210],ans[210];
    int n;
    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]),a[i][j]*=1.00;
            double res=a[i][1];
            for(int j=1;j<=n+1;j++)
                a[i][j]=(double)a[i][j]/res;
        }
        for(int i=1;i<=n;i++){
            if (a[i][i]==0) {puts("No solution"); return 0;}
            for(int j=i+1;j<=n+1;++j)
                a[i][j]/=a[i][i];
            a[i][i]=1;
            for(int j=i+1;j<=n;j++) {
                for(int k=i+1;k<=n+1;k++)
                    a[j][k]-=a[j][i]*a[i][k];
                a[j][i]=0;
            }
        }
        for(int i=n;i>=1;i--) {
            double res=a[i][n+1];
            for(int j=i+1;j<=n;j++) res-=ans[j]*a[i][j];
            ans[i]=res/a[i][i];
        }
        for(int i=1;i<=n;i++) printf("%.0lf
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    Queryable.Union 方法实现json格式的字符串合并
    战舰少女官方网站正式开启 -手机卡牌游戏
    星工场逆转娱乐圈预计5.1后上线
    Eclipse编辑jsp卡死解决方案
    Eclipse的workspace中放入Ext JS卡死或OOM的解决方案
    Ext Js详解指南
    Android 自定义RadioButton实现
    反编译Android APK及防止APK程序被反编译
    Android自定义控件
    优秀博客
  • 原文地址:https://www.cnblogs.com/logic-yzf/p/7695115.html
Copyright © 2020-2023  润新知