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;
}