zl程序教程

您现在的位置是:首页 >  其它

当前栏目

JDOJ 1234: VIJOS-P1052 高斯消元

高斯消 vijos
2023-09-11 14:20:14 时间

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;
}