CSP认证:202009-4 星际旅行

题目链接:点击这里

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<deque>//代码写的有点丑
#include<cmath>
using namespace std;
const double pi=acos(-1.0);
double kkk[2005][105];
double ctr[105];
double disr[2005];
int main(){
   	int n,m;
	double r;
   	scanf("%d%d",&n,&m);scanf("%lf",&r);
   	for(int i=1;i<=n;++i) scanf("%lf",&ctr[i]);
   	for(int i=1;i<=m;++i) for(int j=1;j<=n;++j) scanf("%lf",&kkk[i][j]);
	for(int i=1;i<=m;++i){
		double ans=0;
		for(int j=1;j<=n;++j){
			ans+=(double)((kkk[i][j]-ctr[j])*(kkk[i][j]-ctr[j]));
		}
		disr[i]=sqrt(ans);
	}
	for(int i=1;i<=m;++i){
		double iui=0;
		for(int j=1;j<=m;++j){//这里开数组记录的话可以少跑一半的复杂度,我偷懒了。。。
			if(i==j) continue;
			double diss=0;
			for(int k=1;k<=n;++k){
				diss+=(double)((kkk[i][k]-kkk[j][k])*(kkk[i][k]-kkk[j][k]));
			}
			diss=sqrt(diss);
			double p=(disr[i]+disr[j]+diss)/2.0;
			double aera=sqrt(p*(p-disr[i])*(p-disr[j])*(p-diss));
			double hhh=aera*2.0/diss;
			//情况有4种:1段直线,1段弧线,1段弧线和1段直线,1段弧线和2段直线
			if(hhh>=r||disr[i]*disr[i]+diss*diss<=disr[j]*disr[j]||disr[j]*disr[j]+diss*diss<=disr[i]*disr[i]){
				iui+=diss;continue;
			}
			//上边是1段直线的情况
			//下边直接把后三种情况合一
			double cosc=(disr[i]*disr[i]+disr[j]*disr[j]-diss*diss)/(2*disr[i]*disr[j]);
			double tht=acos(cosc);
			double k1=sqrt(disr[i]*disr[i]-1.0*r*r),k2=sqrt(disr[j]*disr[j]-1.0*r*r);
			double tht1= acos( (disr[i]*disr[i]+1.0*r*r-k1*k1)/(2.0*disr[i]*r) );
			double tht2= acos( (disr[j]*disr[j]+1.0*r*r-k2*k2)/(2.0*disr[j]*r) );
			double tht3=tht-tht1-tht2;double k3=r*tht3;
			iui+=k1+k2+k3;
		}
		printf("%.15f\n",iui);
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值