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 }