2022.2.26 学习 CSP 202009-4 星际旅行
参考博客:第二十次csp认证 第四题 星际旅行题解(大佬啊)
其实我之前不是很懂弧度和角度的区别…:C++中tan、atan、sin、cos等三角函数用法的代码演示及结果,注意角度和弧度的转换!
心得: 仔细分析题目,寻找解题方式,然后再代码,不要一头雾水的一遍写代码一遍瞎想。。
少起一些乱七八糟的变量名。。。。能避免重复计算就尽量避免
#include <bits/stdc++.h>
using namespace std;
int n,m,r;
int o[101];
int s[2001][101];//m个点
double d[2001];//m个点到o点的距离
double rd[2001];//m个点与圆做切线,点到切点的距离
double result[2001][2001]={0};
int main()
{
std::ios::sync_with_stdio(false);
cin>>n>>m;
cin>>r;
for(int i=1;i<=n;i++)
{
cin>>o[i];
}
for(int i=1;i<=m;i++)
{
int tmp=0;
for(int j=1;j<=n;j++)
{
cin>>s[i][j];
tmp+=(s[i][j]-o[j])*(s[i][j]-o[j]);
}
d[i]=sqrt(tmp);
rd[i]=sqrt(tmp-r*r);
}
for(int i=1;i<=m;i++)
{
for(int j=i+1;j<=m;j++)
{
double tmp=0;
for(int k=1;k<=n;k++)
{
tmp+=(s[i][k]-s[j][k])*(s[i][k]-s[j][k]);
}
double x=sqrt(tmp);
double p=(d[i]+d[j]+x)/2;
double s=sqrt(p*(p-d[i])*(p-d[j])*(p-x));
double h=2*s/x;
if(h>=r || (x*x+d[j]*d[j]<=d[i]*d[i]) || (x*x+d[i]*d[i]<=d[j]*d[j]))
{
result[i][j]=result[j][i]=x;
continue;
}
else
{
double j1=acos((d[i]*d[i]+d[j]*d[j]-x*x)/(2*d[i]*d[j]));
//(d[i]*d[i]+d[j]*d[j]-x*x)/(2*d[i]*d[j])得到的是该角的cos值,使用反cos即acos求该角对应的弧长
double j2=acos(r/d[i]);
double j3=acos(r/d[j]);
double hu=(j1-j2-j3)*r;
result[i][j]=result[j][i]=hu+rd[i]+rd[j];
}
}
}
for(int i=1;i<=m;i++)
{
double sum=0;
for(int j=1;j<=m;j++)
{
sum+=result[i][j];
}
cout<<setiosflags(ios::fixed)<<setprecision(14)<<sum<<endl;
}
return 0;
}