Case 1: 0.7071067812
题意:在一个多边形内画一个多边形求能让一个圆在两个多边形之间自由穿行的最小半径
解题思路:想的是能自由穿行所以应该是两个多边形轮廓相距的最小距离;所以就想采取枚举内多变形定点到外多变形各边的最小距离算出这些距离中最小的即可。就在网上找了点到线段距离的最短距离的代码代进去AC看来思路应该是正确的。
附:点到线段最短距离参考博客:http://blog.csdn.net/yjukh/article/details/5213577
AC代码:
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#define eps 1e-8using namespace std;struct point{double x,y;}A[110],B[110];double MIN(double a,double b){return a<b?a:b;}double GetPointDistance(point p1, point p2) { return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}double GetNearestDistance(point PA, point PB, point P3){//----------ͼ2-------------------- double a,b,c; a=GetPointDistance(PB,P3); if(a<=0.00001) return 0.0f; b=GetPointDistance(PA,P3); if(b<=0.00001) return 0.0f; c=GetPointDistance(PA,PB); if(c<=0.00001) return a;//Èç¹ûPAºÍPB×ø±êÏàͬ£¬ÔòÍ˳öº¯Êý£¬²¢·µ»Ø¾àÀë//------------------------------ if(a*a>=b*b+c*c)//--------ͼ3-------- return b; //Èç¹ûÊǶ۽Ƿµ»Øb if(b*b>=a*a+c*c)//--------ͼ4------- return a; //Èç¹ûÊǶ۽Ƿµ»Øa //ͼ1 double l=(a+b+c)/2; //Öܳ¤µÄÒ»°ë double s=sqrt(l*(l-a)*(l-b)*(l-c)); //º£Â×¹«Ê½ÇóÃæ»ý£¬Ò²¿ÉÒÔÓÃʸÁ¿Çó return 2*s/c;} int main(){int t,k=1,n,m,i,j;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=0;i<n;++i){scanf("%lf%lf",&A[i].x,&A[i].y);}scanf("%d",&m);for(i=0;i<m;++i){scanf("%lf%lf",&B[i].x,&B[i].y);}double ans=1e20;for(i=0;i<n;++i){for(j=0;j<m;++j){ans=MIN(ans,GetNearestDistance(B[j],B[(j+1)%m],A[i]));}}printf("Case %d: %.7lf\n",k++,ans/2.0);}return 0;}