poj 3525

多边形内最大半径圆。

哇没有枉费了我自闭了这么些天,大概五天前我看到这种题可能毫无思路抓耳挠腮举手投降什么的,现在已经能1A了哇。

还是先玩一会计算几何,刷个几

嗯这个半平面交+二分就阔以解决。虽然队友说他施展三分套三分*****

想象一下,如果一个多边形能放进去半径为r的圆,那么在每条边向里平移r之后,他的内核一定不为空。

所以我们可以二分r,然后求半平面交,平移操作其实很好处理。

1A了很开森,去快乐的玩耍惹。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <cmath>
  6 #include <deque>
  7 using namespace std;
  8 typedef double db;
  9 const db eps=1e-6;
 10 const db pi=acos(-1);
 11 int sign(db k){
 12     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
 13 }
 14 int cmp(db k1,db k2){return sign(k1-k2);}
 15 struct point{
 16     db x,y;
 17     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
 18     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
 19     point operator * (db k1) const{return (point){x*k1,y*k1};}
 20     point operator / (db k1) const{return (point){x/k1,y/k1};}
 21     db abs(){return sqrt(x*x+y*y);}
 22     point unit(){db w=abs(); return point{x/w,y/w};}
 23     point turn90(){ return point{-y,x};}
 24     db getP()const { return sign(y)==1||(sign(y)==0&&sign(x)==-1);}
 25 };
 26 db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
 27 db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
 28 db rad(point k1,point k2){ return atan2(cross(k1,k2),dot(k1,k2));}
 29 int compareangle(point k1,point k2){
 30     return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>0);
 31 }
 32 point getLL(point k1,point k2,point k3,point k4){
 33     db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3);
 34     return (k1*w2+k2*w1)/(w1+w2);
 35 }
 36 struct line{
 37     point p[2];
 38     line(point k1,point k2){p[0]=k1;p[1]=k2;}
 39     point &operator[](int k){ return p[k];}
 40     int include(point k){ return sign(cross(p[1]-p[0],k-p[0])>0);}
 41     point dir(){ return p[1]-p[0];}
 42     line push(db eps){//向左手边平移eps
 43         //const db eps=1e-6;
 44         point delta=(p[1]-p[0]).turn90().unit()*eps;
 45         return {p[0]-delta,p[1]-delta};
 46     }
 47 };
 48 point getLL(line k1,line k2){
 49     return getLL(k1[0],k1[1],k2[0],k2[1]);
 50 }
 51 int parallel(line k1,line k2){ return sign(cross(k1.dir(),k2.dir()))==0;}
 52 int sameDir(line k1,line k2){
 53     return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==1;
 54 }
 55 int operator <(line k1,line k2){
 56     if(sameDir(k1,k2))return k2.include(k1[0]);
 57     return compareangle(k1.dir(),k2.dir());
 58 }
 59 int checkpos(line k1,line k2,line k3){ return k3.include(getLL(k1,k2));}
 60 vector<line> getHL(vector<line> &L){
 61     sort(L.begin(),L.end());deque<line> q;
 62     for(int i=0;i<L.size();i++){
 63         if(i&&sameDir(L[i],L[i-1]))continue;
 64         while (q.size()>1&&!checkpos(q[q.size()-2],q[q.size()-1],L[i]))q.pop_back();
 65         while (q.size()>1&&!checkpos(q[1],q[0],L[i]))q.pop_front();
 66         q.push_back(L[i]);
 67     }
 68     while (q.size()>2&&!checkpos(q[q.size()-2],q[q.size()-1],q[0]))q.pop_back();
 69     while (q.size()>2&&!checkpos(q[1],q[0],q[q.size()-1]))q.pop_front();
 70     vector<line> ans;for(int i=0;i<q.size();i++)ans.push_back(q[i]);
 71     return ans;
 72 }
 73 point p[1551];
 74 int n;
 75 bool cw(){//时针
 76     db s=0;
 77     for(int i=1;i<n-1;i++){
 78         s+=cross(p[i]-p[0],p[i+1]-p[0]);
 79     }
 80     return s>0;
 81 }
 82 vector<line> L,tmp;
 83 bool check(db x){
 84     tmp.clear();
 85     for(int i=0;i<L.size();i++){
 86         tmp.push_back(L[i].push(-x));
 87     }
 88     tmp = getHL(tmp);
 89     if(tmp.size()>=3)
 90         return true;
 91     return false;
 92 }
 93 int main(){
 94     //freopen("3525.in","r",stdin);
 95     while (scanf("%d",&n)&&n){
 96         for(int i=0;i<n;i++){
 97             scanf("%lf%lf",&p[i].x,&p[i].y);
 98         }
 99         if(!cw())reverse(p,p+n);
100         for(int i=0;i<n;i++){
101             L.push_back(line(p[i],p[(i+1)%n]));
102         }
103         db l = 0,r=100000.0;
104         while (l+0.0000001<r){
105             db mid = (l+r)/2;
106             if(check(mid))
107                 l=mid;
108             else
109                 r=mid;
110         }
111         printf("%.7f\n",l);
112         L.clear();
113     }
114 }
View Code

 

posted @ 2019-02-28 23:34  MXang  阅读(215)  评论(0编辑  收藏  举报