[BZOJ 1013]球型空间产生器
转载请注明出处:http://danihao123.is-programmer.com/
不行不能颓了……线代其实刚起步……
注意每个点到球心的距离相同,距离之平方亦相同。然后假设所有半径平方为[tex]d[/tex],那么我们先可以列出两个方程(假设[tex]n=2[/tex],不过此时事实上可以列三个,但出于方便讨论的目的便只列两个):
[tex](x_1-a_1)^2+(x_2-a_2)^2=d[/tex]
[tex](x_1-b_1)^2+(x_2-b_2)^2=d[/tex]
两方程作差,得:
[tex](x_1-a_1)^2+(x_2-a_2)^2-(x_1-b_1)^2-(x_2-b_2)^2=0[/tex]
整理,得:
[tex]2(b_1-a_1)x_1+2(b_2-a_2)x_2=(b_1+a_1)(b_1-a_1)+(b_2+a_2)(b_2-a_2)[/tex]
对这种方法加以推广,便可列出[tex]n[/tex]个[tex]n[/tex]元一次方程。高斯消元求解即可。
代码:
/**************************************************************
Problem: 1013
User: danihao123
Language: C++
Result: Accepted
Time:4 ms
Memory:1296 kb
****************************************************************/
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=20;
int n;
double M[maxn][maxn];
double A[maxn][maxn];
inline void Gause(){
register int i,j,k,r;
register double f;
for(i=1;i<=n;i++){
r=i;
for(j=i+1;j<=n;j++)
if(fabs(A[j][i])>fabs(A[r][i]))
r=j;
if(r!=i)
for(j=1;j<=(n+1);j++)
swap(A[r][j],A[i][j]);
for(k=i+1;k<=n;k++){
f=A[k][i]/A[i][i];
for(j=i;j<=n+1;j++)
A[k][j]-=f*A[i][j];
}
}
for(i=n;i>=1;i--){
for(j=i+1;j<=n;j++)
A[i][n+1]-=A[j][n+1]*A[i][j];
A[i][n+1]/=A[i][i];
}
}
int main(){
register int i,j;
bool flag=false;
cin>>n;
for(i=1;i<=(n+1);i++)
for(j=1;j<=n;j++)
cin>>M[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=(n+1);j++)
A[i][j]=0;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
A[i][j]=2*(M[i+1][j]-M[i][j]);
A[i][n+1]+=(M[i+1][j]-M[i][j])*(M[i+1][j]+M[i][j]);
}
}
Gause();
for(i=1;i<=n;i++){
if(flag)
putchar(' ');
flag=true;
printf("%.3f",A[i][n+1]);
}
putchar('\n');
return 0;
}
评论 (0)