半平面交的学习戳这里:http://blog.csdn.net/accry/article/details/6070621

  然而这题是要二分长度r……用每条直线的距离为r的平行线来截“凸包”

  做平行线的方法是:对于向量(x,y),与它垂直的向量有:(y,-x)和(-y,x),然后再转化成单位向量,再乘以 r ,就得到了转移向量tmp,设直线上两点为A(x1,y1),B(x2,y2),用这个方法就找到了直线AB的平行线CD,其中C=A+tmp,D=b+tmp;

  然而我傻逼的搞错了方向……结果平行线做成了远离凸包的那一条……导致答案一直增大QAQ

  剩下的就没啥了,看是否存在这么一块半平面的交即可。

  1 Source Code
  2 Problem: 3525        User: sdfzyhy
  3 Memory: 672K        Time: 16MS
  4 Language: G++        Result: Accepted
  5 
  6     Source Code
  7 
  8     //POJ 3525
  9     #include<cmath>
 10     #include<cstdio>
 11     #include<cstring>
 12     #include<cstdlib>
 13     #include<iostream>
 14     #include<algorithm>
 15     #define rep(i,n) for(int i=0;i<n;++i)
 16     #define F(i,j,n) for(int i=j;i<=n;++i)
 17     #define D(i,j,n) for(int i=j;i>=n;--i)
 18     using namespace std;
 19     typedef long long LL;
 20     inline int getint(){
 21         int r=1,v=0; char ch=getchar();
 22         for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
 23         for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
 24         return r*v;
 25     }
 26     const int N=110;
 27     const double eps=1e-6,INF=1e8;
 28     /*******************template********************/
 29 
 30 
 31     int n;
 32     struct Poi{
 33         double x,y;
 34         Poi(){}
 35         Poi(double x,double y):x(x),y(y){}
 36         void read(){scanf("%lf%lf",&x,&y);}
 37         void out(){printf("%f %f\n",x,y);}
 38     }p[N],tp[N],s[N],o;
 39     typedef Poi Vec;
 40     Vec operator - (const Poi &a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);}
 41     Vec operator + (const Poi &a,const Vec &b){return Poi(a.x+b.x,a.y+b.y);}
 42     Vec operator * (const double &k,const Vec a){return Vec(a.x*k,a.y*k);}
 43     inline double Cross(const Vec &a,const Vec &b){return a.x*b.y-a.y*b.x;}
 44     inline double Dot(const Vec &a,const Vec &b){return a.x*b.x+a.y*b.y;}
 45     inline double Len(const Vec &a){return sqrt(Dot(a,a));}
 46     inline int dcmp(double x){return x > eps ? 1 : x < eps ? -1 : 0;}
 47     double getarea(Poi *a,int n){
 48         double ans=0.0;
 49         F(i,1,n) ans+=Cross(a[i]-o,a[i+1]-o);
 50         return ans*0.5;
 51     }
 52     Poi getpoint (const Poi &a,const Poi &b,const Poi &c,const Poi &d){
 53         Poi ans,tmp=b-a;
 54         double k1=Cross(d-a,c-a),k2=Cross(c-b,d-b);
 55         ans=a+(k1/(k1+k2))*tmp;
 56         return ans;
 57     }
 58     inline void get_parallel(Poi &a,Poi &b,double r,Poi &c,Poi &d){
 59     //    Poi tmp(b.y-a.y,a.x-b.x);
 60         Poi tmp(a.y-b.y,b.x-a.x);
 61         tmp=(r/Len(tmp))*tmp;
 62         c=a+tmp; d=b+tmp;
 63     //    a.out(); b.out(); c.out(); d.out();
 64     //    puts("");
 65     }
 66     void init(){
 67         F(i,1,n) p[i].read();
 68         p[n+1]=p[1];
 69     }
 70     bool check(double r){
 71         tp[1]=tp[5]=Poi(-INF,-INF);
 72         tp[2]=Poi(INF,-INF);
 73         tp[3]=Poi(INF,INF);
 74         tp[4]=Poi(-INF,INF);
 75         int num=4,size=0;
 76         F(i,1,n){
 77             size=0;
 78             F(j,1,num){
 79                 Poi t1(0,0),t2(0,0);
 80                 get_parallel(p[i],p[i+1],r,t1,t2);
 81                 if (dcmp(Cross(t2-t1,tp[j]-t1))>=0)
 82                     s[++size]=tp[j];
 83                 if (dcmp(Cross(t2-t1,tp[j]-t1)*Cross(t2-t1,tp[j+1]-t1))<0)
 84                     s[++size]=getpoint(t1,t2,tp[j],tp[j+1]);
 85             }
 86             s[size+1]=s[1];
 87             F(j,1,size+1) tp[j]=s[j];
 88             num=size;
 89     //        printf("num=%d\n",num);
 90     //        F(j,1,num) tp[j].out();
 91         }
 92     //    printf("n=%d num=%d size=%d\n",n,num,size);
 93         if  (num>0) return 1;
 94         else return 0;
 95     }
 96     int main(){
 97     #ifndef ONLINE_JUDGE
 98         freopen("3525.in","r",stdin);
 99         freopen("3525.out","w",stdout);
100     #endif
101         while(scanf("%d",&n)!=EOF && n){
102             init();
103             double l=0.0,r=1e7,mid;
104             while(r-l>eps){
105                 mid=(l+r)/2;
106     //            printf("mid=%f\n",mid);
107                 if (check(mid)) l=mid;
108                 else r=mid;
109             }
110             printf("%f\n",l);
111         }
112         return 0;
113     }
View Code

相关文章: