1. 程式人生 > 實用技巧 >JDOJ 1234: VIJOS-P1052 高斯消元

JDOJ 1234: VIJOS-P1052 高斯消元

JDOJ 1234: VIJOS-P1052 高斯消元

JDOJ傳送門

Description

​ 賈老二是個品學兼優的好學生,但由於智商問題,算術學得不是很好,尤其是在解方程這個方面。雖然他解決 2x=2 這樣的方程遊刃有餘,但是對於 {x+y=3 x-y=1} 這樣的方程組就束手無策了。於是他要你來幫忙。前提是一次方程組且保證在integer的範圍內可以處理所有問題。

Input

​ 第一行一個數字N(1≤N≤100)表示要求的未知數的個數,同時也是所給的方程個數。 第2到N+1行,每行N+1個數。前N個表示第1到N個未知數的係數。第N+1個數表示N個未知數乘以各自係數後的加和。(保證有唯一整數解)

Output

​ 一行N個數,表示第1到N個未知數的值。

Sample Input

2 1 1 3 1 -1 1

Sample Output

2 1


題解:

高斯消元模板題。

關於高斯消元,請走:

淺談高斯消元

WA6次PE一次。

不愧是我

注意精度問題:首先不能無腦int,因為要四捨五入。

然後不能無腦輸出,因為可能會出現-0的情況(四捨五入後)。所以這裡還要判一下這種情況。

程式碼:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-6;
int n;
double a[110][110],b[110];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            scanf("%lf",&a[i][j]);
        scanf("%lf",&b[i]);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
            if(fabs(a[j][i])>eps)
            {
                for(int k=1;k<=n;k++)
                    swap(a[j][k],a[i][k]);
                swap(b[i],b[j]);
            }
        for(int j=1;j<=n;j++)
        {
            if(i==j)
                continue;
            double rate=a[j][i]/a[i][i];
            for(int k=1;k<=n;k++)
                a[j][k]-=a[i][k]*rate;
            b[j]-=b[i]*rate;
        }
    }
    for(int i=1;i<n;i++)
    {
        double ans=b[i]/a[i][i];
        if(fabs(ans)<eps)
            printf("%.0lf ",fabs(ans));
        else
            printf("%.0lf ",ans);
    }
    double ans=b[n]/a[n][n];
    if(fabs(ans)<eps)
        printf("%.0lf",fabs(ans));
    else
        printf("%.0lf",ans);
    return 0;
}