CodeForces 613 A. Peter and Snow Blower(计算几何)

Description
给出圆心o的坐标和n个点的坐标,问以o为圆心且覆盖这n个点的圆环的最小面积
Input
第一行三个整数n,x,y分别表示点数和圆心o的坐标,之后n行每行两个整数xi,yi表示该点坐标,以顺时针或者逆时针顺序输入,且保证不存在三点共线的情况
(3<=n<=100000,-10^6<=xi,yi<=10^6)
Output
输出以o为圆心且覆盖这n个点的圆环的最小面积
Sample Input
3 0 0
0 1
-1 2
1 2
Sample Output
12.566370614359172464
Solution
问题转化为o点到n个点的最远距离以及o点到n个线段的最近距离
Code

#include
#include
#include
#include
#include
using namespace std;
#define maxn 111111
#define INF 0x7f7f7f7f7f
#define PI acos(-1.0)
struct node
{
    double x,y;
}o,p[maxn];
int n;
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double get_dis(node a,node b,node c)
{   
    double A=dis(b,c),B=dis(a,c),C=dis(a,b);
    if(A*A+C*C<=B*B)return A;
    if(B*B+C*C<=A*A)return B;
    double s=abs((a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x));
    return s/dis(a,b);
}
int main()
{
    while(~scanf("%d%lf%lf",&n,&o.x,&o.y))
    {
        double Min=INF,Max=0;
        for(int i=0;iscanf("%lf%lf",&p[i].x,&p[i].y);
            double temp=dis(p[i],o);
            Max=max(Max,temp);
        }   
        for(int i=0;iint j=(i+1)%n;
            Min=min(Min,get_dis(p[i],p[j],o));
        }
        printf("%.10lf\n",(Max*Max-Min*Min)*PI);
    }
    return 0;
}

你可能感兴趣的:(Code,Forces,计算几何)