凸包,凸包,凸包。。。T T 。。
今天上午在机组课看算导看懂了~~~,下午算法实验课,花了快一节课才想对><。。。那神马叉积,弄得我头大。。不过算导这个算法讲解得很详细,在纸上画画也差不多了。。。算法不解释,看算导吧。
这题就是求凸包的点连成环的长度。n = 1和2的时候需要特殊处理,开始我2没有乘2,WA得一塌糊涂T T 。。
这个没有加精度判断。。。
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <math.h> using namespace std; const int MAX = 120; typedef struct Point{ double x,y; }Point; Point c[MAX]; double crossProduct(Point a,Point b,Point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool cmp(Point a,Point b) { if( a.y == b.y ) return a.x < b.x; return a.y < b.y; } bool cmp1(Point a,Point b) { return crossProduct(c[0],a,b) < 0 ? 1 : 0; } double Distance(Point a,Point b) { return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) ); } Point stk[MAX]; int top; double dis() { double sum = 0.0; for(int i=0; i<top; i++) sum += Distance(stk[i],stk[i+1]); sum += Distance(stk[top],stk[0]); return sum; } double Graham(int n) { sort(c,c+n,cmp); sort(c+1,c+n,cmp1); top = 0; stk[top++] = c[0]; stk[top++] = c[1]; stk[top++] = c[2]; top--; for(int i=3; i<n; i++) { while(1) { Point a,b; a = stk[top]; b = stk[top-1]; if( crossProduct(a,b,c[i]) < 0 ) top--; else break; } stk[++top] = c[i]; } return dis(); } int main() { int n; while( ~scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf %lf",&c[i].x,&c[i].y); if( n == 1 ) { printf("0.00/n"); continue; } if( n == 2 ) { printf("%.2lf/n",2*Distance(c[0],c[1])); continue; } double ans = Graham(n); printf("%.2lf/n",ans); } return 0; }
加精度判断的
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <math.h> using namespace std; const int MAX = 120; const double eps = 1e-6; typedef struct Point{ double x,y; }Point; Point c[MAX]; bool dy(double x,double y) // x > y { return x > y + eps; } bool xy(double x,double y) // x < y { return x < y - eps; } bool dyd(double x,double y) // x >= y { return x > y - eps; } bool xyd(double x,double y) // x <= y { return x < y + eps; } bool dd(double x,double y) // x == y { return fabs( x - y ) < eps; } double crossProduct(Point a,Point b,Point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool cmp(Point a,Point b) { if( dd(a.y ,b.y ) ) return xy(a.x, b.x); return xy(a.y,b.y); } bool cmp1(Point a,Point b) { return xy( crossProduct(c[0],a,b), 0.0 ); } double Distance(Point a,Point b) { return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) ); } Point stk[MAX]; int top; double dis() { double sum = 0.0; for(int i=0; i<top; i++) sum += Distance( stk[i], stk[i+1] ); sum += Distance( stk[top], stk[0] ); return sum; } void Graham(int n) { sort(c,c+n,cmp); sort(c+1,c+n,cmp1); top = 0; stk[top++] = c[0]; stk[top++] = c[1]; stk[top++] = c[2]; top--; for(int i=3; i<n; i++) { while(1) { Point a,b; a = stk[top]; b = stk[top-1]; if( xy( crossProduct(a,b,c[i]), 0.0 ) ) top--; else break; } stk[++top] = c[i]; } for(int i=0; i<=top; i++) cout << c[i].x << ' ' << c[i].y << endl; } int main() { int n; while( ~scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf %lf",&c[i].x,&c[i].y); Graham(n); } return 0; }