標籤:bzoj bzoj1013 高斯消元
題目大意:給定n維空間下的n+1個點,求這n個點所在的球面的球心
曾經嘗試了很久的類比退火0.0 至今仍未AC 0.0
今天挖糞塗牆怒學了高斯消元……
我們設球心為X(x1,x2,...,xn)
假設有兩點A(a1,a2,...,an)和B(b1,b2,...,bn)
那麼我們可以得到兩個方程
(x1-a1)^2+(x2-a2)^2+...+(xn-an)^2=r^2
(x1-b1)^2+(x2-b2)^2+...+(xn-bn)^2=r^2
這些方程都是二次的,無法套用高斯消元
但是我們可以做一些處理 將上面兩個方程相減可得
(a1-b1)x1+(a2-b2)x2+...+(an-bn)xn=[ (a1^2-b1^2)+(a2^2-b2^2)+...+(an^2-bn^2) ]/2
r被消掉,n個方程,n個未知數套用高斯消元模板即可
一直在糾結類比退火為啥切不掉0.0
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 20using namespace std;int n;double pos[M],a[M][M],ans[M];int main(){int i,j,k;cin>>n;for(i=1;i<=n;i++)scanf("%lf",&pos[i]);for(i=1;i<=n;i++){double temp[M];for(j=1;j<=n;j++){scanf("%lf",&temp[j]);a[i][j]=pos[j]-temp[j];a[i][n+1]+=pos[j]*pos[j]-temp[j]*temp[j];}a[i][n+1]/=2;}for(i=1;i<=n;i++){k=0;for(j=i;j<=n;j++)if( fabs(a[j][i])>fabs(a[k][i]) )k=j;for(j=1;j<=n+1;j++)swap(a[i][j],a[k][j]);for(j=i+1;j<=n;j++){double temp=-a[j][i]/a[i][i];for(k=i;k<=n+1;k++)a[j][k]+=a[i][k]*temp;}}for(i=n;i;i--){for(j=n;j>i;j--)a[i][n+1]-=a[i][j]*ans[j];ans[i]=a[i][n+1]/a[i][i];}for(i=1;i<=n;i++)printf("%.3lf%c",ans[i],i==n?'\n':' ');}
BZOJ 1013 JSOI2008 球形空間產生器sphere 高斯消元