很简单,裸的最小圆覆盖。同 zoj 1450.
10005 - Packing polygons
Time limit: 3.000 seconds
Packing polygons
Given a polygon of
n points (not necessarily convex), your goal is to say whether there is a circle of a given a radius
R that contains the polygon or not.
Packing polygons |
Input
The input consists of several input cases. The first line of each input case is the number n (with n < 100) of vertices in the polygon. Then you are given n lines each containing a couple of integers that define the coordinates of the vertices. The last line of the input case will be a real number indicating the radius R of the circle.The end of the input will be signaled by an input case with n = 0 vertices, that must not be processed.
You may assume that no vertex will appear twice in any given input case.
Output
If the polygon can be packed in a circle of the given radius you have to print:
The polygon can be packed in the circle.
If the polygon cannot be packed you have to print:
There is no way of packing that polygon.
Sample Input
3 0 0 1 0 0 1 1.0 3 0 0 1 0 0 1 0.1 0
Sample Output
The polygon can be packed in the circle. There is no way of packing that polygon.
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#define maxn 1005
using namespace std;
struct tpoint
{
double x,y;
tpoint operator -(const tpoint &a) const
{
tpoint p1;
p1.x=x-a.x;
p1.y=y-a.y;
return p1;
}
};
struct tcircle
{
double r;
tpoint centre;
};
struct ttriangle
{
tpoint t[3];
};
tcircle c;
tpoint a[maxn];
double distances(tpoint p1,tpoint p2)
{
tpoint p3;
p3.x=p2.x-p1.x;
p3.y=p2.y-p1.y;
return sqrt(p3.x*p3.x+p3.y*p3.y);
}
double trianglearea(ttriangle t)
{
tpoint p1,p2;
p1=t.t[1]-t.t[0];
p2=t.t[2]-t.t[0];
return fabs(p1.x*p2.y-p1.y*p2.x)/2;
}
tcircle circumcircleoftriangle(ttriangle t)
{
tcircle tmp;
double a,b,c,c1,c2;
double xa,xb,xc,ya,yb,yc;
a = distances( t.t[0] , t.t[1] );
b=distances(t.t[1],t.t[2]);
c=distances(t.t[2],t.t[0]);
tmp.r=a*b*c/trianglearea(t)/4;
xa=t.t[0].x;ya=t.t[0].y;
xb=t.t[1].x;yb=t.t[1].y;
xc=t.t[2].x;yc=t.t[2].y;
c1=(xa*xa+ya*ya-xb*xb-yb*yb)/2;
c2=(xa*xa+ya*ya-xc*xc-yc*yc)/2;
tmp.centre.x=(c1*(ya-yc)-c2*(ya-yb))/
((xa-xb)*(ya-yc)-(xa-xc)*(ya-yb));
tmp.centre.y=(c1*(xa-xc)-c2*(xa-xb))/
((ya-yb)*(xa-xc)-(ya-yc)*(xa-xb));
return tmp;
}
tcircle mincircle2(int tce,ttriangle ce)
{
tcircle tmp;
if(tce == 0) tmp.r=-2;
else if(tce == 1)
{
tmp.centre=ce.t[0];
tmp.r=0;
}
else if(tce == 2)
{
tmp.r=distances(ce.t[0],ce.t[1])/2;
tmp.centre.x=(ce.t[0].x+ce.t[1].x)/2;
tmp.centre.y=(ce.t[0].y+ce.t[1].y)/2;
}
else if(tce == 3)
tmp=circumcircleoftriangle(ce);
return tmp;
}
void mincircle(int t,int tce,ttriangle ce)
{
int i,j;
tpoint tmp;
c=mincircle2(tce,ce);
if(tce == 3) return ;
for(i=1;i<=t;i++)
{
if(distances(a[i],c.centre)>c.r)
{
ce.t[tce]=a[i];
mincircle(i-1,tce+1,ce);
tmp=a[i];
for(j = i;j>=2;j--)
{
a[j]=a[j-1];
}
a[1]=tmp;
}
}
}
void run(int n)
{
ttriangle ce;
int i;
mincircle(n,0,ce);
// printf("%.2lf %.2lf %.2lf\n",c.centre.x,c.centre.y,c.r);
}
int main()
{
int n;
double rr;
while(scanf("%d",&n)!=EOF && n)
{
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
cin>>rr;
run(n);
if(c.r<=rr) cout<<"The polygon can be packed in the circle."<<endl;
else cout<<"There is no way of packing that polygon."<<endl;
}
return 0;
}