凸包问题
来源:互联网 发布:淘宝详情页宽度是多少 编辑:程序博客网 时间:2024/05/19 20:42
凸包问题
凸包基础知识见:http://baike.baidu.com/view/707209.htm 或者,
参考《国际大学生程序设计竞赛例题解 》(一)计算几何部分和LRJ的黑书。
研究了两天的凸包问题,也在POJ上找了几道题目练习了一下,这里给出自己写的
Graham扫描法求凸包的模板\源代码:/*--------------------------------------------------------------------// Abstract: Graham扫描法求凸包 // Author:王莉峰(Fandywang) // History:2007-11-21 // Version:Microsoft Visual C++6.0 //--------------------------------------------------------------------*/#include #include #include typedef struct CPoint{ double x, y;}Point;const int MAXSIZE = 10000;const double EPS = 1E-6;int stack[MAXSIZE]; //数组模拟堆栈,存放凸包的逆序顶点int top; //凸包顶点数p[stack[0]...stack[top]]Point p[MAXSIZE];void GrahamScan(const int &n); //Graham扫描法求凸包double Dist(const Point &arg1, const Point &arg2); //两点距离double Length(const int &n); //多边形周长double Area(const int &n); //多边形面积void Swap(const int &i, const int &j); //交换两个点double Multi(const Point &p0, const Point &p1, const Point &p2); //叉积运算int cmp(const void *arg1, const void *arg2); //自定义排序:按照极角int main(void){ int n;// freopen("Input.txt", "r", stdin); while( scanf("%d", &n), n ) { int i; for( i=0; i < n; ++i ) { scanf("%lf %lf", &p[i].x, &p[i].y); } if( n == 1 ) { printf("周长: 0.00\t面积: 0.00\n"); } else if( n == 2 ) { printf("周长: %.2lf\t面积: 0.00\n", Dist(p[0], p[1])); } else { GrahamScan(n); /* for( int k=0; k <= top; ++k ) { printf("%lf %lf\n", p[stack[k]].x, p[stack[k]].y); }*/ printf("周长: %.2lf\t面积: %.2lf\n", Length(top+1), Area(top+1)); } } return 0;}double Length(const int &n){ double sum = Dist( p[stack[n-1]], p[stack[0]] ); for( int i = 0; i < n-1; ++i ) { sum += Dist( p[stack[i]], p[stack[i+1]] ); } return sum;}double Area(const int &n){ double area = 0; for( int i=0; i < n-1; ++i ) { area += (p[stack[i]].x*p[stack[i+1]].y) - (p[stack[i+1]].x*p[stack[i]].y); } area = fabs(area) / 2; return area;}double Dist(const Point &arg1, const Point &arg2){ return sqrt( (arg1.x - arg2.x)*(arg1.x - arg2.x) + (arg1.y - arg2.y)*(arg1.y - arg2.y) );}void Swap(const int &i, const int &j){ Point temp = p[i]; p[i] = p[j]; p[j] = temp;}//通过矢量叉积求极角关系(p0p1)(p0p2)//P*Q > 0,P在Q的顺时针方向... ...double Multi(const Point &p0, const Point &p1, const Point &p2){ return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int cmp(const void *arg1, const void *arg2){ Point a = *(Point*)arg1; Point b = *(Point*)arg2; double k = Multi(p[0], a, b); if( k < -EPS ) return 1; else if( fabs(k) < EPS && (Dist(a, p[0]) - Dist(b, p[0])) > EPS ) return 1; else return -1;}void GrahamScan(const int &n){ int i, u = 0; for( i = 1; i < n; ++i ) {//找到最左下的顶点, 令其为p[0] if( ( p[i].y < p[u].y ) || ( p[i].y == p[u].y && p[i].x < p[u].x ) ) u = i; } i = 0; Swap(i, u); //只交换一次 //将点按照相对p[0]的极角从小到大排序, 用qsort qsort( p+1, n-1, sizeof(p[0]), cmp ); //将每一个点逐一检验, 是凸包点放入栈中, 不是则弹出栈。 //注意: 排序后, p[0]和p[1]一定是凸包的顶点 stack[0] = 0; stack[1] = 1; stack[2] = 2; top = 2; for( int j = 3; j < n; ++j ) { while( Multi( p[j], p[stack[top]], p[stack[top-1]] ) > 0 ) { --top; if( top == 0 ) break; } stack[++top] = j; }}
//凸包题目:
POJ 1113 Wall 凸包的基本应用
POJ 1228 Grandpa's Estate 凸包拓展
POJ 2187 Beauty Contest 用凸包求最远点对
提高题目:
POJ 1794 Castle Walls
POJ 2007 Scrambled Polygon
0 0
- 凸包问题
- 凸包问题
- poj2187 凸包问题
- 凸包问题
- ACM -- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题-蛮力法
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- ACM:凸包问题
- hdu 1392 凸包问题
- iOS 9功能
- Hashtable、synchronizedMap、ConcurrentHashMap 比较
- Java对象序列化
- Objective-C:#include与#import的区别
- java程序的内存分配
- 凸包问题
- 微信分享
- jdbc预编译
- #pragma 预处理指令详解
- Java数据库连接池比较(c3p0,dbcp,proxool和BoneCP)
- HTTP协议Keep-Alive模式详解
- http长连接与短连接
- 九度oj-1370-数组中出现次数超过一半的数字
- Oracle SQL性能优化