Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

hdu 3934 Summer holiday http://acm.hdu.edu.cn/showproblem.php?pid=3934

旋转卡壳凸包,最大三角形面积

View Code
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const double eps=1e-8;
 7 const double pi=acos(-1.0);
 8 inline double dcmp(double d)
 9 {
10     return d<-eps?-1:d>eps;
11 }
12 struct Point
13 {
14     double x,y;
15     Point(double _x=0,double _y=0)
16     :x(_x),y(_y){}
17     Point operator + (const Point &p)const
18     {
19         return Point(x+p.x,y+p.y);
20     }
21     Point operator - (const Point &p)const
22     {
23         return Point(x-p.x,y-p.y);
24     }
25     double operator * (const Point &p)
26     {
27         return x*p.y-y*p.x;
28     }
29     bool operator < (const Point &p)const
30     {
31         return (y+eps<p.y || (y<p.y+eps && x+eps<p.x));
32     }
33     void input()
34     {
35         scanf("%lf%lf",&x,&y);
36     }
37 };
38 double area(Point &a,Point &b,Point &c)
39 {
40     return fabs(a*b+b*c+c*a)/2;
41 }
42 const int maxP=1000010;
43 struct Polygon
44 {
45     int n;
46     Point p[maxP];
47     void input()
48     {
49         for(int i=0;i<n;i++) p[i].input();
50     }
51     void ConvexHull(Polygon &c)
52     {
53         sort(p,p+n);
54         int &m=c.n;
55         m=0;
56         for(int i=0;i<n;i++)
57         {
58             while(m>1 && dcmp((c.p[m-1]-c.p[m-2])*(p[i]-c.p[m-2]))<=0) m--;
59             c.p[m++]=p[i];
60         }
61         int k=m;
62         for(int i=n-2;i>=0;i--)
63         {
64             while(m>k && dcmp((c.p[m-1]-c.p[m-2])*(p[i]-c.p[m-2]))<=0) m--;
65             c.p[m++]=p[i];
66         }
67         if(n>1) m--;
68     }
69     double getans()
70     {
71         double ans=0;
72         for(int i=0;i<n;i++)
73             for(int j=(i+1)%n,k=(j+1)%n;j!=i && k!=i;j=(j+1)%n)
74             {
75                 while(area(p[i],p[j],p[k])<area(p[i],p[j],p[k+1])) k=(k+1)%n;
76                 ans=max(ans,area(p[i],p[j],p[k]));
77             }
78         return ans;
79     }
80 };
81 
82 Polygon a,b;
83 int main()
84 {
85 //freopen("in.txt","r",stdin);
86     while(~scanf("%d",&a.n))
87     {
88         a.input();
89         a.ConvexHull(b);
90         double ans=b.getans();
91         printf("%.2lf\n",ans+eps);
92     }
93     return 0;
94 }

 

 hdu 2440 Watch out the Animal http://acm.hdu.edu.cn/showproblem.php?pid=2440

模拟退火凸包费马点,求到凸多边形顶点的距离之和的最小值

View Code
  1 #include <cstdio>
  2 #include <cmath>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 #define sqr(x) ((x)*(x))
  7 #define eps 1e-8
  8 inline int dcmp(double d)
  9 {
 10     return d<eps?-1:d>eps;
 11 }
 12 struct Point
 13 {
 14     double x,y;
 15     Point(double _x=0,double _y=0)
 16     :x(_x),y(_y){}
 17     double dis(Point p)
 18     {
 19         return sqrt(sqr(x-p.x)+sqr(y-p.y));
 20     }
 21     Point operator + (const Point &p)const
 22     {
 23         return Point(x+p.x,y+p.y);
 24     }
 25     Point operator - (const Point &p)const
 26     {
 27         return Point(x-p.x,y-p.y);
 28     }
 29     Point operator * (double k)const
 30     {
 31         return Point(x*k,y*k);
 32     }
 33     double operator * (const Point &p)
 34     {
 35         return x*p.y-y*p.x;
 36     }
 37     bool operator < (const Point &p)const
 38     {
 39         return (x+eps<p.x || (x<p.x+eps && y+eps<p.y));
 40     }
 41     void input()
 42     {
 43         scanf("%lf%lf",&x,&y);
 44     }
 45 };
 46 const int maxP=110;
 47 struct Polygon
 48 {
 49     int n;
 50     Point p[maxP];
 51     void input()
 52     {
 53         scanf("%d",&n);
 54         for(int i=0;i<n;i++) p[i].input();
 55     }
 56     void ConvexHull(Polygon &c)
 57     {
 58         sort(p,p+n);
 59         int &m=c.n;
 60         m=0;
 61         for(int i=0;i<n;i++)
 62         {
 63             while(m>1 && dcmp((c.p[m-1]-c.p[m-2])*(p[i]-c.p[m-2]))<=0) m--;
 64             c.p[m++]=p[i];
 65         }
 66         int k=m;
 67         for(int i=n-2;i>=0;i--)
 68         {
 69             while(m>k && dcmp((c.p[m-1]-c.p[m-2])*(p[i]-c.p[m-2]))<=0) m--;
 70             c.p[m++]=p[i];
 71         }
 72         if(n>1) m--;
 73     }
 74 };
 75 
 76 
 77 const Point dir[4]={Point(1,0),Point(0,1),Point(-1,0),Point(0,-1)};
 78 double sumdis(Point a,Point *p,int n)
 79 {
 80     double s=0;
 81     for(int i=0;i<n;i++) s+=a.dis(p[i]);
 82     return s;
 83 }
 84 double SA(Point *p,int n)
 85 {
 86     Point u=p[0];
 87     double ans=sumdis(u,p,n);
 88     for(double len=1e3;len>0.1;len*=0.5)
 89     {
 90         bool flag=true;
 91         while(flag)
 92         {
 93             flag=false;
 94             Point nu=u;
 95             for(int i=0;i<4;i++)
 96             {
 97                 Point v=u+dir[i]*len;
 98                 double tdis=sumdis(v,p,n);
 99                 if(tdis<ans)
100                 {
101                     ans=tdis;
102                     nu=v;
103                     flag=true;
104                 }
105             }
106             u=nu;
107         }
108     }
109     return ans;
110 }
111 
112 Polygon a,b;
113 int main()
114 {
115     int T;
116     scanf("%d",&T);
117     while(T--)
118     {
119         a.input();
120         a.ConvexHull(b);
121         double ans=SA(b.p,b.n);
122         printf("%.0f\n",ans);
123         if(T) printf("\n");
124     }
125     return 0;
126 }

 

hdu 3932 Groundhog Build Home http://acm.hdu.edu.cn/showproblem.php?pid=3932

模拟退火,求最小覆盖圆的圆心和半径,角度划分小点

View Code
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 #define sqr(x) ((x)*(x))
 7 const double pi=acos(-1.0);
 8 struct Point
 9 {
10     double x,y;
11     Point(double _x=0,double _y=0)
12     :x(_x),y(_y){}
13     double dis(Point p)
14     {
15         return sqrt(sqr(x-p.x)+sqr(y-p.y));
16     }
17     void input()
18     {
19         scanf("%lf%lf",&x,&y);
20     }
21 };
22 
23 double maxdis(Point a,Point *p,int n)
24 {
25     double s=0;
26     for(int i=0;i<n;i++) s=max(s,a.dis(p[i]));
27     return s;
28 }
29 void SA(Point *p,int n)
30 {
31     Point u=p[0];
32     double ans=maxdis(u,p,n);
33     for(double len=1e3;len>1e-3;len*=0.5)
34     {
35         bool flag=true;
36         while(flag)
37         {
38             flag=false;
39             Point nu=u;
40             for(double ang=0;ang<2*pi;ang+=pi/30)
41             {
42                 Point v=u;
43                 v.x=u.x+len*cos(ang);
44                 v.y=u.y+len*sin(ang);
45                 double tdis=maxdis(v,p,n);
46                 if(tdis<ans)
47                 {
48                     ans=tdis;
49                     nu=v;
50                     flag=true;
51                 }
52             }
53             u=nu;
54         }
55     }
56     printf("(%.1f,%.1f).\n",u.x,u.y);
57     printf("%.1f\n",ans);
58 }
59 
60 Point p[1010];
61 int main()
62 {
63     double x,y;
64     while(~scanf("%lf%lf",&x,&y))
65     {
66         int n;
67         scanf("%d",&n);
68         for(int i=0;i<n;i++) p[i].input();
69         SA(p,n);
70     }
71     return 0;
72 }

 最小覆盖圆,对于第i个点如果在覆盖前i-1的圆外,则第i个点必在圆上,三点求圆心的代码有bug,y=(c1-a1*x)/b1, b1可能等于0

View Code
 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4 
 5 const double eps=1e-8;
 6 struct Point
 7 {
 8     double x,y;
 9     Point(double x=0,double y=0)
10     :x(x),y(y){};
11     double dis(Point p)
12     {
13         return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
14     }
15     void input()
16     {
17         scanf("%lf%lf",&x,&y);
18     }
19 };
20 
21 const int N=1010;
22 Point p[N];
23 Point center(Point a,Point b,Point c)
24 {
25     double a1=2*(a.x-b.x),b1=2*(a.y-b.y),c1=a.x*a.x-b.x*b.x+a.y*a.y-b.y*b.y;
26     double a2=2*(a.x-c.x),b2=2*(a.y-c.y),c2=a.x*a.x-c.x*c.x+a.y*a.y-c.y*c.y;
27     double x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
28     double y=(c1-a1*x)/b1;
29     return Point(x,y);
30 }
31 double MinCoverCircle(Point *p,int n,Point &c)
32 {
33     c=p[0];
34     double r=0;
35     for(int i=1;i<n;i++)
36         if(c.dis(p[i])>r+eps)
37         {
38             c=p[i]; r=0;
39             for(int j=0;j<i;j++)
40                 if(c.dis(p[j])>r+eps)
41                 {
42                     c.x=(p[i].x+p[j].x)/2;
43                     c.y=(p[i].y+p[j].y)/2;
44                     r=c.dis(p[i]);
45                     for(int k=0;k<j;k++)
46                         if(c.dis(p[k])>r+eps)
47                         {
48                             c=center(p[i],p[j],p[k]);
49                             r=c.dis(p[i]);
50                         }
51                 }
52         }
53     return r;
54 }
55 int main()
56 {
57     double x,y;
58     while(~scanf("%lf%lf",&x,&y))
59     {
60         int n;
61         scanf("%d",&n);
62         for(int i=0;i<n;i++) p[i].input();
63         Point c;
64         double r=MinCoverCircle(p,n,c);
65         printf("(%.1f,%.1f).\n",c.x+eps,c.y+eps);
66         printf("%.1f\n",r+eps);
67     }
68     return 0;
69 }

 

hdu 2215 Maple trees http://acm.hdu.edu.cn/showproblem.php?pid=2215

最小覆盖圆,用3932的代码,三点求圆心的bug找了很久,y=(c1-a1*x)/b1, b1可能等于0

View Code
 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4 
 5 const double eps=1e-8;
 6 struct Point
 7 {
 8     double x,y;
 9     Point(double x=0,double y=0)
10     :x(x),y(y){};
11     double dis(Point p)
12     {
13         return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
14     }
15     void input()
16     {
17         scanf("%lf%lf",&x,&y);
18     }
19 };
20 
21 const int N=110;
22 Point p[N];
23 Point center(Point a,Point b,Point c)
24 {
25     double a1=2*(a.x-b.x),b1=2*(a.y-b.y),c1=a.x*a.x-b.x*b.x+a.y*a.y-b.y*b.y;
26     double a2=2*(a.x-c.x),b2=2*(a.y-c.y),c2=a.x*a.x-c.x*c.x+a.y*a.y-c.y*c.y;
27     double x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
28     double y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
29     return Point(x,y);
30 }
31 double MinCoverCircle(Point *p,int n,Point &c)
32 {
33     c=p[0];
34     double r=0;
35     for(int i=1;i<n;i++)
36     {
37         if(c.dis(p[i])+eps<r) continue;
38         c=p[i]; r=0;
39         for(int j=0;j<i;j++)
40         {
41             if(c.dis(p[j])+eps<r) continue;
42             c.x=(p[i].x+p[j].x)/2;
43             c.y=(p[i].y+p[j].y)/2;
44             r=c.dis(p[i]);
45             for(int k=0;k<j;k++)
46             {
47                 if(c.dis(p[k])+eps<r) continue;
48                 c=center(p[i],p[j],p[k]);
49                 r=c.dis(p[i]);
50             }
51         }
52     }
53     return r;
54 }
55 int main()
56 {
57     int n;
58     while(scanf("%d",&n),n)
59     {
60         for(int i=0;i<n;i++) p[i].input();
61         Point c;
62         double r=MinCoverCircle(p,n,c);
63         printf("%.2f\n",r+0.5+eps);
64     }
65     return 0;
66 }

 

 

posted on 2012-11-23 14:11  Qiuqiqiu  阅读(200)  评论(0编辑  收藏  举报