bzoj1013 [JSOI2008]球形空间产生器sphere

题目链接:bzoj1013 luogu4035

\(n\)个未知数\(n+1\)个方程,有鬼

然后你发现这个方程不仅是二次的还带了个未知数\(r\),考虑给方程式进行变形

假设现在有两个方程\(\sum_{i=1}^n(a_i-x_i)^2=r^2,\sum_{i=1}^n(b_i-x_i)^2=r^2\)

消去\(r\)\(\sum_{i=1}^n(a_i-x_i)^2=\sum_{i=1}^n(b_i-x_i)^2\)

消去\(x^2\)并整理含\(x\)的项至一边:\(\sum_{i=1}^n2(b_i-a_i)x_i=\sum_{i=1}^n(b_i^2-a_i^2)\)

\(a_i,b_i\)给定,故可以将原来的\(n+1\)个方程整理至\(n\)个,暴力高斯消元即可

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define fir first
#define sec second
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define maxd 1000000007
#define eps 1e-6
typedef long long ll;
const int N=100000;
const double pi=acos(-1.0);
int n;
double a[110][110],b[110][110],ans[110];

int read()
{
	int x=0,f=1;char ch=getchar();
	while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
	while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
	return x*f;
}

double Fabs(double x)
{
	if (x>eps) return x;else return -x;
}

void gauss()
{
	rep(i,1,n)
	{
		int now=i;
		rep(j,i+1,n)
			if (Fabs(a[j][i])>Fabs(a[now][i])) now=j;
		if (now!=i) swap(a[now],a[i]);
		double div=a[i][i];
		rep(j,i,n+1) a[i][j]/=div;
		rep(j,1,n)
		{
			if (i==j) continue;
			div=a[j][i];
			rep(k,i,n+1) a[j][k]-=div*a[i][k];
			a[j][i]=0.0;
		}
	}
}

int main()
{
	n=read();
	rep(i,1,n+1)
		rep(j,1,n) scanf("%lf",&b[i][j]);
	rep(i,1,n)
	{
		rep(j,1,n)
		{
			a[i][j]=((b[i+1][j]-b[i][j])*2.0);
			a[i][n+1]+=(sqr(b[i+1][j])-sqr(b[i][j]));
		}
	}
	gauss();
	rep(i,1,n) printf("%.3lf ",a[i][n+1]);
	return 0;
}
posted @ 2019-05-04 00:22  EncodeTalker  阅读(116)  评论(0编辑  收藏  举报