hdu 3847 Trash Removal(简单几何)

http://acm.hdu.edu.cn/showproblem.php?pid=3847

 

 题意:
给你一个多边形(不一定凸),求最小平行线的距离,使这个多边线能通过。
思路:
先做个凸包,然后把离凸包每条边最远的点的距离求出来,这些距离里的最
小值即为所求 


我的代码:


/*
program:hdu_3847
author:BlackAndWhite
*/ 

#include<stdio.h>
#include<algorithm>
#include<math.h>
#define eps 1e-7
using namespace std;
struct Lpoint
{
    double x,y;
}pnt[105],res[105];
struct Ldir{double dx,dy;};
struct Lline{Lpoint p;Ldir dir;};
int n,i,j,nr,js=1;
double tans,ans,tt;
bool mult(Lpoint sp,Lpoint ep,Lpoint op)
{
    return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);
}
bool operator < (const Lpoint &l, const Lpoint &r)
{
    return l.y<r.y||(l.y==r.y&&l.x<r.x);
}
int graham(Lpoint pnt[],int n,Lpoint res[])
{
    int i,len,k=0,top=1;
    sort(pnt,pnt+n);
    if(n==0) return 0;res[0]=pnt[0];
    if(n==1) return 1;res[1]=pnt[1];
    if(n==2) return 2;res[2]=pnt[2];
    for(i=2;i<n;i++)
    {
        while(top&&mult(pnt[i],res[top],res[top-1]))
            top--;
        res[++top]=pnt[i];
    }
    len=top;res[++top]=pnt[n-2];
    for(i=n-3;i>=0;i--)
    {
        while(top!=len&&mult(pnt[i],res[top],res[top-1]))
            top--;
        res[++top]=pnt[i];
    }
    return top;
}
void format(Lline ln,double &A,double &B,double &C)
{
    A=ln.dir.dy;
    B=-ln.dir.dx;
    C=ln.p.y*ln.dir.dx-ln.p.x*ln.dir.dy;
}
double p2dis(Lpoint a,Lline ln)
{
    double A,B,C;
    format(ln,A,B,C);
    return(fabs(A*a.x+B*a.y+C)/sqrt(A*A+B*B));
}
int main()
{
    while(scanf("%d",&n),n)
    {
        for(i=0;i<n;i++)
            scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
        nr=graham(pnt,n,res);
        res[nr]=res[0];
        ans=1e9;
        Lline TmpLine;//临时开的直线 
        for(i=0;i<nr;i++)//找离直线最远的距离 
        {
            tans=0;
            TmpLine.p=res[i];
            TmpLine.dir.dx=res[i].x-res[i+1].x;
            TmpLine.dir.dy=res[i].y-res[i+1].y;
            for(j=0;j<nr;j++)
            {
                tt=p2dis(res[j],TmpLine);
                if(tt>tans) tans=tt;
            }
            if(tans<ans) ans=tans;    
        }
        printf("Case %d: %.2lf\n",js++,ans+0.005-eps);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值