【凸包】Exactness of Projectile Hit

来源:互联网 发布:数据处理软件 编辑:程序博客网 时间:2024/04/27 21:27

1215. Exactness of Projectile Hit

Time Limit: 1.0 second
Memory Limit: 16 MB
Inexactness of projectile hit may be compensated
by increasing of the projectile diameter.
Sergey Sizy
Problem illustration
In the problem you are to determine the minimal diameter that may compensate inexactness of projectile hit in each concrete case. Assume that all the targets are convex polygons. A hit is the situation when the circle crater that the projectile leaves (the crater diameter equals to the one of the projectile) covers if only one point of the target.

Input

The first line contains three numbers — coordinates of the hit point of the projectile center and the number of polygon sidesN (3 ≤N ≤ 100). The next N lines contain the vertices coordinates in counter-clockwise order. All the coordinates are integers from [−2000,2000].

Output

You are to output the only number which is the minimal diameter of a projectile that will cover the target rounded with three digits after the decimal point.

Sample

inputoutput
2 -1 80 11 02 03 13 22 31 30 2
2.000
Problem Author: Anton Botov and Anatoly Uglov
Problem Source: USU Open Collegiate Programming Contest October'2002 Junior Session


被坑了,一开始以为是凸包Graham算法,结果后来Wjj才告诉我,题目给出的就是一个凸包,而且顺序都排好了。。。

四个知识点:

1、判断一个点S是否在凸多边形内,每一条边的方向向量AB和向量BS的叉乘结果,AB×BS>0,则在凸包内。只要有一条边AB×BS<0,则在凸包内。

2、一个点到一条线段的距离,不能直接用向量×法向量÷法向量的模,直线和线段不同,要先判断∠SAB和∠SBA是否均为锐角,若非则输出SA和SB的之间的最小值。(复数求法向量即乘以i)

3、不能直接和0比较大小,要和eps或-eps比较。<=0即<eps,>=0即>-eps,<0即<eps,>0即>eps

4、对实数取绝对值要用fabs不能用abs。


#include <cstdio>#include <cmath>#include <algorithm>using std::min;double eps = 1e-8;double inf = 1e19;long n;struct Point{double x;double y;double abs(){return sqrt(x*x+y*y);}Point(double _x,double _y):x(_x),y(_y){}Point(){}Point operator-(Point& n2){return Point(x-n2.x,y-n2.y);}}pos[110];Point Sp;double dist(Point a,Point b,Point c){    Point ca = a-c;    Point ba = a-b;    Point cb = b-c;    Point bc = c-b;    double multi1 = ca.x*cb.x+ca.y*cb.y;    double multi2 = ba.x*bc.x+ba.y*bc.y;    if (multi1<-eps || multi2<-eps)    {return min((b-a).abs(),(c-a).abs());}    else    {        Point ver = Point(-cb.y,cb.x);        double multi3 = ca.x*ver.x+ca.y*ver.y;        return fabs(multi3/ver.abs());    }}double cross_product(Point p1,Point p2){return p1.x*p2.y-p2.x*p1.y;}int main(){freopen("eoph.in","r",stdin);freopen("wyh.out","w",stdout);long x;long y;scanf("%ld%ld%ld",&x,&y,&n);Sp = Point(x,y);for (long i=1;i<n+1;i++){scanf("%ld%ld",&x,&y);pos[i].x = x;pos[i].y = y;}double ans = 1e19;bool inside = true;for (long i=1;i<n+1;i++){long next = i+1;if (next == n+1) next = 1;ans = min(ans,dist(Sp,pos[next],pos[i]));inside &= (cross_product(pos[next]-pos[i],Sp-pos[next])>-eps);}if (inside){printf("0\n");return 0;}printf("%.3lf\n",ans*2);return 0;}


原创粉丝点击