The Shape of Donggua 工大的原创几何题 挺好,顶一下。

来源:互联网 发布:怎么让淘宝卖家封店 编辑:程序博客网 时间:2024/05/16 10:17

/*就是用凸包和旋转卡壳求一个最远点对和最近的距离。这个最近的距离定义为用两条平行直线将多边形包围时直线中的所有距离里求最小即可。只需要在卡到最远点跳出while循环时记录下此时最远点到边的距离即可。我用叉积来记录。然后不断更新最小值即可。*/#include <stdio.h>#include <iostream>#include <algorithm>#include <cmath>#define ll 0.618-0.1#define rr 0.618+0.1#define inf 9999999999.0#define eps 1e-8using namespace std;struct point{    double x,y;} res[10001],p[10001];int n,top;double cross(point a,point b,point o){    return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);}double dis(point a,point b){    return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}bool cmp(point a,point b){    if(a.x-b.x>eps||b.x-a.x>eps) return a.x<b.x;    return a.y<b.y;}void graham(){    sort(p,p+n,cmp);    res[0] = p[0];    res[1] = p[1];    top = 1;    for(int i=2; i<n; i++)    {        while(top&&cross(p[i],res[top-1],res[top])<=0)            --top;        res[++top] = p[i];    }    int ntop = top;    res[++top] = p[n-2];    for(int i=n-3; i>=0; i--)    {        while(top>ntop&&cross(p[i],res[top-1],res[top])<=0)            --top;        res[++top] = p[i];    }}int main(){    while(scanf("%d",&n)==1)    {        for(int i=0; i<n; i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        graham();        int q=1;        double L=0,S=0;        double min=inf;        double sum=0;        for(int i=0; i<top; i++)        {            while(fabs(cross(res[i],res[i+1],res[q]))<fabs(cross(res[i],res[i+1],res[q+1])))                q=(q+1)%top;            L=max(L,max(dis(res[i],res[q]),dis(res[i+1],res[q+1])));            sum=fabs(cross(res[i],res[i+1],res[q]));            S=sum/sqrt(dis(res[i],res[i+1]));            if(S<min) min=S;        }        L=sqrt(L);        double t=min/L;        if(t>=ll&&t<=rr) printf("Proper\n");        else if(t<ll) printf("Thin\n");        else if(t>rr) printf("Fat\n");            }    return 0;}