球面距离
题目大意
给定两个点的经度和纬度,求两个点的球面距离,半径为地球半径6370km。经度和纬度给定分和秒,需要转化。
代码
主要就是要学习球面距离的求法,即转化为圆心角和半径的乘积。
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pi 3.141592653589793238462643383279
using namespace std;
typedef long long ll;
const int lmax = 5e3 + 10;
const int mod = 1e9 + 7;
double sph_dis(double wd1,double jd1,double wd2,double jd2,double r)//已知纬度,经度,半径,求球面两点之间的球上距离
{//经度和纬度都转换成弧度制
double x1,x2,y1,y2,z1,z2;
x1=cos(wd1)*cos(jd1);
y1=cos(wd1)*sin(jd1);
z1=sin(wd1);
x2=cos(wd2)*cos(jd2);
y2=cos(wd2)*sin(jd2);
z2=sin(wd2);
double a=acos(x1*x2+y1*y2+z1*z2);//圆心角
return r*a;
}
int main()
{
double w1,wm1,j1,jm1,wd1,jd1;
double w2,wm2,j2,jm2,wd2,jd2;
char chr1,chr2;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %c %lf %lf %c",&w1,&wm1,&chr1,&j1,&jm1,&chr2);
wd1=(w1+wm1/60)*pi/180;
jd1=(j1+jm1/60)*pi/180;
if(chr1=='S')
wd1*=-1.0;
if(chr2=='W')
jd1*=-1.0;
scanf("%lf %lf %c %lf %lf %c",&w2,&wm2,&chr1,&j2,&jm2,&chr2);
wd2=(w2+wm2/60)*pi/180;
jd2=(j2+jm2/60)*pi/180;
if(chr1=='S')
wd2*=-1.0;
if(chr2=='W')
jd2*=-1.0;
printf("%.3lf\n",sph_dis(wd1,jd1,wd2,jd2,6370.0));
}
return 0;
}
/*
2
55 0 N 40 0 E
59 0 N 49 30 E
40 0 N 0 0 E
40 0 N 180 0 E
*/
圆覆盖点
题目大意
在二维平面给定很多点,问一个单位圆最多能覆盖多少点。
代码
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pi 3.141592653589793238462643383279
#define eps 1e-6
using namespace std;
typedef long long ll;
struct Point
{
double x,y;
}point[301];
double dis(Point p1,Point p2)//两点间距离的平方
{
return (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);
}
Point find_start(Point p1,Point p2)
{
Point p,mid,start;
double d,aa;
p.x=p2.x-p1.x;
p.y=p2.y-p1.y;
mid.x=(p1.x+p2.x)/2;
mid.y=(p1.y+p2.y)/2;
d=sqrt(1-dis(p1,mid));
if(fabs(p.y)<eps)//公共弦垂直于X轴
{
start.x=mid.x;
start.y=mid.y+d;
}
else//公共弦不垂直于X轴
{
aa=atan(-p.x/p.y);//公共弦的倾斜角
start.x=mid.x+d*cos(aa);
start.y=mid.y+d*sin(aa);
}
return start;
}
int main()
{
int n,ans,ans0;
int i,j,k;
Point centre;
double tmp;
while(~scanf("%d",&n))
{
if(n==0)
break;
for(i=0;i<n;i++)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
}
ans=1;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(dis(point[i],point[j])>4)
continue;
ans0=0;
centre=find_start(point[i],point[j]);
for(k=0;k<n;k++)
{
tmp=dis(centre,point[k]);
if(tmp<=1.000001)
ans0++;
}
if(ans<ans0)
ans=ans0;
}
printf("%d\n",ans);
}
return 0;
}
/*
3
6.47634 7.69628
5.16828 4.79915
6.69533 6.20378
6
7.15296 4.08328
6.50827 2.69466
5.91219 3.86661
5.29853 4.16097
6.10838 3.46039
6.34060 2.41599
0
*/