您的位置:首页 > 其它

UVALive - 4062 You are around me ...

2014-10-18 15:25 281 查看
几何+二分+优化

这种题做起来其实挺爽的,做完之后特有成就感,也学到了很多东西。

首先要对点的坐标进行旋转,这里是二维的,还可以有三维甚至更多的,牵扯到线性代数知识。。。越来越觉得数学太重要了。。为什么一开始学数学的时候老师没有告诉我们数学的用处之大呢。。。。

然后是二分,题目中说对精度要求不高,但还是必须小于1E-9

但只有这些会超时,解决办法是按横坐标排序,中心距离大于当前a的二倍的可以忽略不考虑。。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define MAX 16000
#define INF 1e11
#define EPS 1e-9
#define PI 3.1415926535897
using namespace std;

struct node
{
double x,y;
bool operator<(node other)
{
return x<other.x;
}
}s[MAX];

double front,rear,mid,theta,e,sinn,coss;

int dist1(int a,int b)
{
double help1,help2,dist;
help1=(s[a].x-s[b].x),help2=(s[a].y-s[b].y);
dist=help1*help1+help2*help2;
if(dist<=4*mid*mid)
return 1;
else
return 0;
}

int dist2(int a,int b)
{
double x=(s[a].x+s[b].x)/2,y=(s[a].y+s[b].y)/2,help1,help2;
help1=(x-s[a].x),help2=(y-s[a].y);
if((1-e*e)*(help1*help1-mid*mid)+(help2*help2)<0)
return 1;
else
return 0;
}

int main()
{
int n,i,j,t=1;
double a,b;
while(scanf("%d %lf %lf",&n,&e,&theta)&&n)
{
sinn=sin(theta/180*PI),coss=cos(theta/180*PI);
for(i=0;i<n;i++)
{
scanf("%lf %lf",&a,&b);
s[i].x=a*coss+b*sinn,s[i].y=b*coss-a*sinn;
}
front=0,rear=INF;
sort(s,s+n);
while(rear-front>EPS)
{
mid=(front+rear)/2;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(s[j].x-s[i].x>mid*2+0.1)
break;
if(dist1(i,j))
{
if(dist2(i,j))
{
rear=mid;
goto next;
}
}
}
}
front=mid;
next:
{ }
}
printf("Case %d:\n%.6lf\n",t++,PI*front*front*sqrt(1-e*e));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: