标签:problem init ret opera play class def inter name
题目链接:https://vjudge.net/problem/POJ-3525
二分最大内切圆的半径,然后把求多边形内核的那几个向量向内平移半径。若是构成内核,则半径符合,反之不符合。
如何判断是否构成内核?由于内核是若干个向量围起来的,所以只要向量大于等于3即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 #define eps 1e-8 7 const int N = 107; 8 const double pi = acos(-1.0); 9 int n; 10 struct Point{ 11 double x,y; 12 Point operator - (const Point& b)const{ 13 return (Point){x-b.x,y-b.y}; 14 } 15 double operator ^ (const Point& b)const{ 16 return x*b.y - b.x*y; 17 } 18 Point operator * (const double b){ 19 return (Point){x*b,y*b}; 20 } 21 Point operator + (const Point& b)const{ 22 return (Point){x+b.x,y+b.y}; 23 } 24 }p[N],quep[N]; 25 struct Line{ 26 Point s,t; 27 double ang; 28 bool operator < (const Line& o)const{ 29 if(o.ang != ang) return ang < o.ang; 30 return ( (o.t-s)^(o.s - s) ) > 0; 31 } 32 }L[N],teml[N],quel[N]; 33 int sgn(double x){ 34 if(fabs(x) < eps) return 0; 35 if(x < 0 ) return -1; 36 return 1; 37 } 38 Point cal(Point p,double ag,double d){ 39 Point ans; 40 ans.x = p.x + d*sin(ag); 41 ans.y = p.y - d*cos(ag); 42 return ans; 43 } 44 void init(double d){ 45 for(int i = 1;i <= n ;++i){ 46 L[i].ang = teml[i].ang; 47 L[i].s = cal(teml[i].s,L[i].ang,d); 48 L[i].t = cal(teml[i].t,L[i].ang,d); 49 } 50 } 51 bool onleft(Point u,Line a){ 52 return sgn( (a.s - u)^(a.t - u) ) > 0; 53 } 54 Point line_inter(Line l1,Line l2){ 55 double b = ((l1.t-l1.s)^(l2.s-l1.s))/((l2.t-l2.s)^(l1.t-l1.s)); 56 return l2.s + (l2.t - l2.s)*b; 57 } 58 bool judge(double d){ 59 // cerr<<L[1].s.x<<‘ ‘<<L[1].s.y<<‘ ‘<<L[1].t.x<<‘ ‘<<L[1].t.y<<‘ ‘<<L[1].ang/pi*180<<endl; 60 // cerr<<2.5*sin(L[1].ang)<<‘ ‘<<2.5*cos(L[1].ang)<<endl; 61 // cerr<<d<<endl; 62 init(d); 63 int h,t; 64 h = t = 1; 65 quel[1] = L[1]; 66 for(int i =2; i<=n;++i){ 67 // cerr<<‘a‘<<teml[i].s.x<<‘ ‘<<teml[i].s.y<<‘ ‘<<teml[i].t.x<<‘ ‘<<teml[i].t.y<<‘ ‘<<d<<endl; 68 // cerr<<L[i].s.x<<‘ ‘<<L[i].s.y<<‘ ‘<<L[i].t.x<<‘ ‘<<L[i].t.y<<‘ ‘<<d<<endl; 69 while ( h<t && onleft(quep[t-1],L[i])) --t; 70 while ( h<t && onleft(quep[h],L[i])) ++h; 71 quel[++t] = L[i]; 72 if( h<t ) quep[t-1] = line_inter(quel[t-1],quel[t]); 73 } 74 while( h<t && onleft(quep[t-1],quel[h])) --t; 75 quep[t] = line_inter(quel[h],quel[t]); 76 // cerr<<t<<‘ ‘<<h<<endl; 77 return t-h > 1; 78 } 79 int main(){ 80 while(~scanf("%d",&n) && n){ 81 for(int i = 1;i<=n;++i) scanf("%lf %lf",&p[i].x,&p[i].y); 82 reverse(p+1,p+1+n); 83 p[n+1] = p[1]; 84 for(int i = 1;i <= n ;++i) teml[i]=(Line){p[i],p[i+1],atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x)}; 85 sort(teml+1,teml+1+n); 86 int nn = 1; 87 for(int i = 2;i <= n; ++i){ 88 if(teml[i].ang != teml[i-1].ang) teml[++nn] = teml[i]; 89 } 90 n = nn; 91 double l = 0,r = 10000000,res; 92 while((r-l) >= eps){ 93 double mid = (l+r)/2; 94 if(judge(mid)){ 95 res = mid; 96 l = mid; 97 } 98 else r = mid; 99 } 100 printf("%.6f\n",res); 101 } 102 return 0; 103 }
【poj3525】计算凸多边形最大内切圆(模板 半平面交向量平移)
标签:problem init ret opera play class def inter name
原文地址:https://www.cnblogs.com/xiaobuxie/p/11615367.html