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;
}
原文地址:https://www.cnblogs.com/encodetalker/p/10807201.html