【Luogu】P4035球形空间产生器(高斯消元)

  题目链接

  水比题,把圆方程展开减一下把平方都减掉半径的平方也减掉,高斯消元即可。

  然后我只输出两位小数,爆了两次零。我好菜啊。

  

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
#define maxn 20
#define eps 1e-9
using namespace std;

double s[maxn*maxn][maxn];
double q[maxn][maxn];

double ans[maxn];

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n+1;++i)
        for(int j=1;j<=n;++j)    scanf("%lf",&q[i][j]);
    int m=0;
    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n+1;++j){
            double *c=s[++m];
            for(int k=1;k<=n;++k){
                c[k]=2*(q[i][k]-q[j][k]);
                c[n+1]+=q[i][k]*q[i][k]-q[j][k]*q[j][k];
            }
        }
    //for(int i=1;i<=m;++i,printf("\n"))
    //    for(int j=1;j<=n+1;++j)    printf("%.2lf ",s[i][j]);
    for(int i=1;i<=n;++i){
        int now=i;
        for(int j=i+1;j<=m;++j)
            if(fabs(s[j][i])-fabs(s[now][i])>eps)    now=j;
        if(now^i)    swap(s[i],s[now]);
        double ret=s[i][i];
        for(int j=i;j<=n+1;++j)    s[i][j]=s[i][j]/ret;
        for(int j=i+1;j<=m;++j){
            ret=s[j][i];
            for(int k=1;k<=n+1;++k)    s[j][k]=s[j][k]-s[i][k]*ret;
        }
    }
    ans[n]=s[n][n+1];
    //for(int i=1;i<=m;++i,printf("\n"))
    //    for(int j=1;j<=n+1;++j)    printf("%.2lf ",s[i][j]);
    for(int i=n-1;i;--i){
        ans[i]=s[i][n+1];
        for(int j=i+1;j<=n;++j)    ans[i]=ans[i]-ans[j]*s[i][j];
    }
    for(int i=1;i<=n;++i)    printf("%.3lf ",ans[i]);
    return 0;
}

 

posted @ 2018-04-09 14:51  Konoset  阅读(131)  评论(0编辑  收藏  举报