/*注意事项
1.c语言中三角函数的用法sin(),asin(),cos(),acos()
2.注意分类讨论的情况,分两点之间的直线是在圆内还是圆外进行讨论
3.注意大数组直接打表,求得的部分结果存好
4. 请以“整数部分、小数点、小数部分”的格式输出实数,并保留不少于 12 位小数结果。采用其他格式(如科学记数法)输出可能无法得分
5.4的含义是用 printf("%.13lf\n", ans)这种形式,并不需要单独设计相应的数据结构,小数点位数只要超过12位即可
*/
#include <bits/stdc++.h>
using namespace std;
int n, m; // n维欧几里得空间宇宙,m个星际旅行坐标
int r; // 黑洞半径为r
int O[105]; // 超球体黑洞的中心O的每一维坐标
int P[2005][105]; // 每个目标点的n维坐标
double dis[2005][2005]; // 两点间的旅行距离
double ans;
long dirdis2[2005][2005]; // 两点间直线距离的平方值
long PO2[2005]; // 每个目标点到黑洞中心距离的平方值
/**计算两点间直线距离的平方值(整型)**/
long caldirdis(int x, int y){
long ans = 0;
for(int j=0;j<n;++j)
ans += (P[x][j]-P[y][j])*(P[x][j]-P[y][j]);
return ans;
}
/**判断连线是否在黑洞外**/
bool isOut(int x, int y) {
// 海伦-秦九韶公式计算三角形面积
double a = sqrt(PO2[x]);
double b = sqrt(PO2[y]);
double c = sqrt(dirdis2[x][y]);
double p = (a + b + c) / 2;
double S = sqrt(p*(p-a)*(p-b)*(p-c));
// 面积公式计算O点到直线xy的距离h
double h = 2 * S / c;
if(h>=r) return 1;
else if(c*c+a*a<=b*b) return 1; // 特殊情况!!!钝角三角形
else if(c*c+b*b<=a*a) return 1; // 特殊情况!!!钝角三角形
else return 0;
}
/**计算x,y两点与O点形成夹角的弧度值**/
double caltheta(int x, int y){
double a = sqrt(PO2[x]);
double b = sqrt(PO2[y]);
double c = sqrt(dirdis2[x][y]);
return acos((a*a+b*b-c*c) / (2*a*b));
}
/**两点间带曲线路程计算**/
double calcirdis(int x, int y) {
double a2 = PO2[x];
double b2 = PO2[y];
/**曲线路程 = 黑洞表面曲线部分 + x点到切点的距离 + y点到切点的距离**/
double part1 = caltheta(x, y)*r - acos(sqrt(r*r/a2))*r - acos(sqrt(r*r/b2))*r;
double part2 = sqrt(a2-r*r);
double part3 = sqrt(b2-r*r);
return part1 + part2 + part3;
}
/**求出两点之间的旅行距离**/
void caldis(int x, int y){
dirdis2[x][y] = caldirdis(x, y); // 先计算两点间直线距离的平方值
dirdis2[y][x] = dirdis2[x][y];
// 判断两点间连线是否在黑洞之外
if(isOut(x, y)){ // 黑洞之外
dis[x][y] = sqrt(dirdis2[x][y]); // 路程为dirdis2开平方
dis[y][x] = dis[x][y];
}
else{ // 黑洞之内
dis[x][y] = calcirdis(x, y); // 调用曲线路程函数计算
dis[y][x] = dis[x][y];
}
}
int main()
{
cin >> n >> m;
cin >> r;
for(int j=0;j<n;++j) cin >> O[j];
for(int i=0;i<m;++i){ // 每个目标点
PO2[i] = 0;
for(int j=0;j<n;++j){ // 每一维坐标
cin >> P[i][j];
PO2[i] += (P[i][j]-O[j])*(P[i][j]-O[j]); // 记录该点到黑洞中心距离的平方值(整型)
}
}
/**求出两点之间的旅行距离**/
for(int i=0;i<m;++i)
for(int j=i+1;j<m;++j)
caldis(i, j);
for(int i=0;i<m;++i){
ans = 0;
for(int j=0;j<m;++j) ans = ans + dis[i][j];
printf("%.13lf\n", ans); // %m.nlf->m:输出数据总的长度,n:小数位数,%lf为double型双精度
}
return 0;
}