UVA 10173 (几何凸包)

判断矩形能包围点集的最小面积:凸包

  1 #include <iostream>
  2 #include <cmath>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <string>
  7 #include <sstream>
  8 #include <algorithm>
  9 #define Max 2147483647
 10 #define INF 0x7fffffff
 11 #define ll long long
 12 #define mem(a,b) memset(a,b,sizeof(a))
 13 #define repu(i, a, b) for(int i = (a); i < (b); i++)
 14 const double PI=-acos(-1.0);
 15 #define eps 1e-8
 16 #define N 50010
 17 using namespace std;
 18 struct Point
 19 {
 20     double x,y;
 21     Point() {}
 22     Point(double x0,double y0):x(x0),y(y0) {}
 23 };
 24 Point p[N];
 25 int con[N];
 26 int cn;
 27 int n;
 28 struct Line
 29 {
 30     Point a,b;
 31     Line() {}
 32     Line(Point a0,Point b0):a(a0),b(b0) {}
 33 };
 34 double Xmult(Point o,Point a,Point b)
 35 {
 36     return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
 37 }
 38 double Dmult(Point o,Point a,Point b)
 39 {
 40     return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y);
 41 }
 42 int Sig(double a)
 43 {
 44     return a<-eps?-1:a>eps;
 45 }
 46 double Dis(Point a,Point b)
 47 {
 48     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 49 }
 50 int cmp(Point a,Point b)
 51 {
 52     double d=Xmult(p[0],a,b);
 53     if(d>0)
 54         return 1;
 55     if(d==0 && Dis(p[0],a)<Dis(p[0],b))
 56         return 1;
 57     return 0;
 58 }
 59 double min(double a,double b)
 60 {
 61     return a<b?a:b;
 62 }
 63 void Graham()
 64 {
 65     int i,ind=0;
 66     for(i=1; i<n; i++)
 67         if(p[ind].y>p[i].y || (p[ind].y==p[i].y) && p[ind].x>p[i].x)
 68             ind=i;
 69     swap(p[ind],p[0]);
 70     sort(p+1,p+n,cmp);
 71     con[0]=0;
 72     con[1]=1;
 73     cn=1;
 74     for(i=2; i<n; i++)
 75     {
 76         while(cn>0 && Sig(Xmult(p[con[cn-1]],p[con[cn]],p[i]))<=0)
 77             cn--;
 78         con[++cn]=i;
 79     }
 80     int tmp=cn;
 81     for(i=n-2; i>=0; i--)
 82     {
 83         while(cn>tmp && Sig(Xmult(p[con[cn-1]],p[con[cn]],p[i]))<=0)
 84             cn--;
 85         con[++cn]=i;
 86     }
 87 }
 88 double Solve()
 89 {
 90     int t,r,l;
 91     double ans=999999999;
 92     t=r=1;
 93     if(cn<3)
 94         return 0;
 95     for(int i=0; i<cn; i++)
 96     {
 97         while(Sig( Xmult(p[con[i]],p[con[i+1]],p[con[t+1]])-
 98                    Xmult(p[con[i]],p[con[i+1]],p[con[t]])   )>0)
 99             t=(t+1)%cn;
100         while(Sig( Dmult(p[con[i]],p[con[i+1]],p[con[r+1]])-
101                    Dmult(p[con[i]],p[con[i+1]],p[con[r]])   )>0)
102             r=(r+1)%cn;
103         if(!i) l=r;
104         while(Sig( Dmult(p[con[i]],p[con[i+1]],p[con[l+1]])-
105                    Dmult(p[con[i]],p[con[i+1]],p[con[l]])   )<=0)
106             l=(l+1)%cn;
107         double d=Dis(p[con[i]],p[con[i+1]]);
108         double tmp=Xmult(p[con[i]],p[con[i+1]],p[con[t]])*
109                    ( Dmult(p[con[i]],p[con[i+1]],p[con[r]])-
110                      Dmult(p[con[i]],p[con[i+1]],p[con[l]]) )/d/d;
111         ans=min(ans,tmp);
112     }
113     return ans;
114 }
115 int main()
116 {
117     int i,T;
118     scanf("%d",&T);
119     repu(kase,1,T+1)
120     {
121         scanf("%d",&n);
122         n *= 4;
123         for(i=0; i<n; i++)
124             scanf("%lf%lf",&p[i].x,&p[i].y);
125         Graham();
126         printf("Case #%d:\n%.0lf\n",kase,Solve());
127     }
128     return 0;
129 }
View Code

 

posted @ 2015-05-30 15:33  一麻袋码的玛侬  阅读(256)  评论(0编辑  收藏  举报