Luogu P4035 球形空间产生器 题解
Luogu P4035 球形空间产生器 题解
题目传送门:P4035 (省选/NOI-)
思路
这道题的难点在于如何将这个连等式转化为方程
我们假设球心的坐标为 \((x_1,x_2,\dots,x_n)\) ,给出的点的坐标依次为 \((a_1,a_2,\dots,a_n),(b_1,b_2,\dots,b_n),\dots,(k_1,k_2,\dots,k_n)\)
根据题目提示,很容易想到以下等式:
\[(a_1-x_1)^2+(a_2-x_2)^2+\dots+(a_n-x_n)^2\\
=(b_1-x_1)^2+(b_2-x_2)^2+\dots+(b_n-x_n)^2\\
=\dots=(k_1-x_1)^2+\dots+(k_n-x_n)^2
\]
我们拆分出其中的两个多项式:
\[(a_1-x_1)^2+(a_2-x_2)^2+\dots+(a_n-x_n)^2\\
=(b_1-x_1)^2+(b_2-x_2)^2+\dots+(b_n-x_n)^2
\]
开括号
\[a_1^2-2a_1x_1+x_1^2+a_2^2-2a_2x_2+x_2^2+\dots+a_n^2-2a_nx_n+x_n^2\\
=b_1^2-2b_1x_1+x_1^2+b_2^2-2b_2x_2+x_2^2+\dots+b_n^2-2b_nx_n+x_n^2
\]
观察到等式两边都有\((x_1^2+x_2^2+\dots+x_n^2)\) ,消去,同时将常数项移至等式右边,将未知数移至等式左边
\[(2b_1-2a_1)x_1+(2b_2-2a_2)x_2+\dots+(2b_n-2a_n)x_n\\
=-a_1^2+b_1^2-a_2^2+b_2^2-\dots-a_n^2+b_n^2
\]
可以发现,对于这 \((n+1)\) 个连等的多项式,我们可以每次取出其中的相邻的两个多项式,然后仿照上面的方法化简,最终得到 \(n\) 个等式构成的 \(n\) 元一次方程组
而解这个方程组则可以使用高斯消元法
代码
#include<bits/stdc++.h>
using namespace std;
#define GO(u,v,i) for(register int i=u;i<=v;i++)
template<class t>inline t fr(){
register t num=0,dis=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')dis=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){num=(num<<1)+(num<<3)+(ch^48);ch=getchar();}
return num*dis;
}
template<class t>inline void fw(t num){
if(num>9)fw(num/10);
putchar(num%10+'0');
}
template<class t>inline void fw(t num,char ch){
if(num<0)num=-num,putchar('-');
fw(num);putchar(ch);
}
typedef double lf;
const int maxn=10+12;
const lf eps=1e-6;
int n;
lf a[maxn][maxn];
inline void gauss(lf a[][maxn],int n){
int maxi;
GO(1,n,i){
maxi=i;
GO(i+1,n,j)if(fabs(a[j][i])>fabs(a[maxi][i]))maxi=j;
if(maxi^i)GO(1,n+1,j)swap(a[i][j],a[maxi][j]);
lf tmp=a[i][i];
GO(i,n+1,j)a[i][j]/=tmp;
GO(i+1,n,j){
if(fabs(a[j][i])>eps){
tmp=a[j][i];
GO(i,n+1,k)a[j][k]-=tmp*a[i][k];
}
}
}
}
inline void prnt(lf a[][maxn],int n){
for(int i=n;i>0;i--){
GO(1,i-1,j)a[j][n+1]-=a[i][n+1]*a[j][i];
if(fabs(a[i][n+1])<eps)a[i][n+1]=0;
}
GO(1,n,i)printf("%.3lf ",a[i][n+1]);
}
signed main(){
n=fr<int>();
GO(1,n+1,i)GO(1,n,j)scanf("%lf",&a[i][j]);
GO(1,n,i){
GO(1,n,j){//常数项
a[i][n+1]-=a[i][j]*a[i][j];
a[i][n+1]+=a[i+1][j]*a[i+1][j];
}
GO(1,n,j){//各项系数
a[i][j]=-2*a[i][j];
a[i][j]+=2*a[i+1][j];
}
}
gauss(a,n);//高斯消元
prnt(a,n);//求解输出
return 0;
}

浙公网安备 33010602011771号