POJ 3525 半平面交

题意:

求多边形的最大内接圆。

 

题解:

二分答案,将所有边向内部逼近,当面积为恰好0时即为最大半径

 

终于写a了一会。。

View Code
  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdio>

  4 #include <cstdlib>

  5 #include <algorithm>

  6 #include <cmath>

  7 

  8 #define N 222

  9 #define PI 3.14159265358979

 10 #define INF 1e9

 11 #define EPS 1e-7

 12 

 13 using namespace std;

 14 

 15 struct PO 

 16 {

 17     double x,y;

 18 }p[N],s[N],tp[N],f[N];

 19 

 20 struct LI

 21 {

 22     PO a,b;

 23 }li[N],sl[N];

 24 

 25 int n;

 26 

 27 inline void prt(PO &a)

 28 {

 29     printf("%lf    %lf\n",a.x,a.y);

 30 }

 31 

 32 inline void read()

 33 {

 34     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);

 35     p[1+n]=p[1];

 36 }

 37 

 38 inline int dc(double x)

 39 {

 40     if(x>EPS) return 1;

 41     else if(x<-EPS) return -1;

 42     return 0;

 43 }

 44 

 45 inline PO operator -(PO a,PO b)

 46 {

 47     PO c;

 48     c.x=a.x-b.x; c.y=a.y-b.y;

 49     return c;

 50 }

 51 

 52 inline PO rotate(PO a,double sss,double ccc)

 53 {

 54     PO ans;

 55     ans.x=ccc*a.x-sss*a.y;

 56     ans.y=sss*a.x+ccc*a.y;

 57     return ans;

 58 }

 59 

 60 inline double getlen(PO &a)

 61 {

 62     return sqrt(a.x*a.x+a.y*a.y);

 63 }

 64 

 65 inline PO getf(PO &a,PO &b)//得到ab左旋90度后的单位向量 

 66 {

 67     PO ans;

 68     ans=b-a;

 69     ans=rotate(ans,sin(0.5*PI),cos(0.5*PI));

 70     double k=getlen(ans);

 71     ans.x/=k; ans.y/=k;

 72     return ans;

 73 }

 74 

 75 inline void prep()

 76 {

 77     for(int i=1;i<=n;i++)

 78     {

 79         f[i]=getf(p[i],p[i+1]);

 80         li[i].a=p[i]; li[i].b=p[i+1];

 81     }

 82 }

 83 

 84 inline void move(double k)

 85 {

 86     for(int i=1;i<=n;i++)

 87     {

 88         sl[i].a.x=li[i].a.x+k*f[i].x;

 89         sl[i].a.y=li[i].a.y+k*f[i].y;

 90         sl[i].b.x=li[i].b.x+k*f[i].x;

 91         sl[i].b.y=li[i].b.y+k*f[i].y;

 92     }

 93 }

 94 

 95 inline double cross(PO &a,PO &b,PO &c)

 96 {

 97     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);

 98 }

 99 

100 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)//直线交点 

101 {

102     PO ans,tp=b-a;

103     double k1=cross(a,d,c);

104     double k2=cross(b,c,d);

105     ans.x=a.x+tp.x*k1/(k1+k2);

106     ans.y=a.y+tp.y*k1/(k1+k2);

107     return ans;

108 }

109 

110 inline int getcut()

111 {

112     tp[1].x=tp[5].x=-INF; tp[1].y=tp[5].y=-INF;

113     tp[2].x=INF,tp[2].y=-INF;

114     tp[3].x=INF,tp[3].y=INF;

115     tp[4].x=-INF,tp[4].y=INF;

116     int cp=4,tc;

117     for(int i=1;i<=n;i++)

118     {

119         tc=0;

120         for(int j=1;j<=cp;j++)

121         {

122             if(dc(cross(sl[i].a,sl[i].b,tp[j]))>=0) s[++tc]=tp[j];

123             if(dc(cross(sl[i].a,sl[i].b,tp[j])*cross(sl[i].a,sl[i].b,tp[j+1]))<0)

124                 s[++tc]=getpoint(sl[i].a,sl[i].b,tp[j],tp[j+1]);

125         }

126         s[tc+1]=s[1];

127         for(int j=1;j<=tc+1;j++) tp[j]=s[j];

128         cp=tc;

129     }

130     return cp;

131 }

132 

133 inline void go()

134 {

135     prep();

136     double l=0.0,r=10000000.0,mid,ans;

137     int cs=100;

138     while(cs--)

139     {

140         mid=(l+r)*0.5;

141         move(mid);

142         if(getcut()) l=mid,ans=mid;

143         else r=mid;

144     }

145     printf("%.6lf\n",ans);

146 }

147 

148 int main()

149 {

150     while(scanf("%d",&n),n) read(),go();

151     return 0;

152 }

 

 

 

你可能感兴趣的:(poj)