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


    Description

    [JSOI2008]球形空间产生器sphere

    Solution

    以二维的时候为例
    球面上三个点分别为((a_1,a_2))((b_1,b_2))((c_1,c_2))
    设球心的点为((x_1,x_2)),球的半径为(T)
    列式得
    (left{ egin{aligned} (a_1-x_1)^2+(a_2-x_2)^2&=(a_1)^2-2a_1x_1+(x_1)^2+(a_2)^2-2a_2x_2+(x_2)^2&=T\ (b_1-x_1)^2+(b_2-x_2)^2&=(b_1)^2-2b_1x_1+(x_1)^2+(b_2)^2-2b_2x_2+(x_2)^2&=T\ (c_1-x_1)^2+(c_2-x_2)^2&=(c_1)^2-2c_1x_1+(x_1)^2+(c_2)^2-2c_2x_2+(x_2)^2&=T end{aligned} ight.)
    联立方程
    ((a_1-x_1)^2+(a_2-x_2)^2=(b_1-x_1)^2+(b_2-x_2)^2=(c_1-x_1)^2+(c_2-x_2)^2)
    暴力展开
    ((a_1)^2-2a_1x_1+(x_1)^2+(a_2)^2-2a_2x_2+(x_2)^2=(b_1)^2-2b_1x_1+(x_1)^2+(b_2)^2-2b_2x_2+(x_2)^2=(c_1)^2-2c_1x_1+(x_1)^2+(c_2)^2-2c_2x_2+(x_2)^2)
    整理得
    ((a_1)^2-2a_1x_1+(a_2)^2-2a_2x_2=(b_1)^2-2b_1x_1+(b_2)^2-2b_2x_2=(c_1)^2-2c_1x_1+(c_2)^2-2c_2x_2)
    也可以写成这个样子
    (left{ egin{aligned} (a_1)^2-2a_1x_1+(a_2)^2-2a_2x_2&=(b_1)^2-2b_1x_1+(b_2)^2-2b_2x_2\ (b_1)^2-2b_1x_1+(b_2)^2-2b_2x_2&=(c_1)^2-2c_1x_1+(c_2)^2-2c_2x_2 end{aligned} ight.)
    移来移去
    (left{ egin{aligned} -2a_1x_1-2a_2x_2+2b_1x_1+2b_2x_2&=-(a_1)^2-(a_2)^2+(b_1)^2+(b_2)^2\ -2b_1x_1-2b_2x_2+2c_1x_1+2c_2x_2&=-(b_1)^2-(b_2)^2+(c_1)^2+(c_2)^2 end{aligned} ight.)
    移来移去
    (left{ egin{aligned} (2b_1-2a_1)x_1+(2b_2-2a_2)x_2&=-(a_1)^2-(a_2)^2+(b_1)^2+(b_2)^2\ (2c_1-2b_1)x_1+(2c_2-2b_2)x_2&=-(b_1)^2-(b_2)^2+(c_1)^2+(c_2)^2 end{aligned} ight.)
    然后我们发现它成了一个(n)元一次方程组,于是我们来高斯消元就行了

    Code

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define eps 1e-7
    #define N 20
    int n;
    double c[N][N], a[N][N], ans[N];
    inline int read() {
    	int s = 0, w = 1;
    	char c = getchar();
    	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    	return s * w;
    }
    int main() {
    	n = read();
    	for (register int i = 1; i <= n + 1; i++)
    		for (register int j = 1; j <= n; j++)
    			scanf("%lf", &c[i][j]);
    	for (register int i = 1; i <= n; i++)
    		for (register int j = 1; j <= n; j++)
    			a[i][j] = - 2 * c[i][j] + 2 * c[i + 1][j],
    			a[i][n + 1] += - c[i][j] * c[i][j] + c[i + 1][j] * c[i + 1][j];
    	for (register int i = 1; i <= n; i++) {
    		int r = i;
    		for (register int j = i + 1; j <= n; j++)
    			if (fabs(a[r][i]) < fabs(a[j][i]))
    				r = j;
    		if (fabs(a[r][i]) < eps) break;
    		if (i != r) swap(a[i], a[r]);
    		double div = a[i][i];
    		for (register int j = i; j <= n + 1; j++)
    			a[i][j] /= div;
    		for (register int j = i + 1; j <= n; j++) {
    			div = a[j][i];
    			for (register int k = i; k <= n + 1; k++)
    				a[j][k] -= a[i][k] * div;
    		}
    	}
    	ans[n] = a[n][n + 1];
    	for (register int i = n - 1; i; i--) {
    		ans[i] = a[i][n + 1];
    		for (register int j = i + 1; j <= n; j++)
    			ans[i] -= a[i][j] * ans[j];
    	}
    	for (register int i = 1; i <= n; i++)
    		printf("%.3lf ", ans[i]);
    	return 0;
    }
    
    只要有想见的人,就不是孤身一人了。
  • 相关阅读:
    js事件绑定函数
    代码练习(二维数组的定义,字符串加减,子元素的创建及绑定,排序算法)
    网页中字符串元素的相减
    JavaScript算法实现排序
    学习英语很重要的一个点
    hasattr(),getattr(),setattr()的使用
    HDU 3746 Cyclic Nacklace
    HDU 1686 Oulipo
    HDU 1711 Number Sequence
    正则表达式的常用操作符
  • 原文地址:https://www.cnblogs.com/Agakiss/p/11825732.html
Copyright © 2020-2023  润新知