UVa 218 - Moth Eradication

来源:互联网 发布:mac微信手机 编辑:程序博客网 时间:2024/05/20 13:39

题目:求凸包上的点和凸包周长。

分析:计算几何、凸包。直接利用graham算法求解即可,按顺时针方向求解,注意叉乘符号。

注意:点小于3个的情况、不过我的凸包算法对n>0都可以求解、而且是所有的点。

#include <algorithm> #include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>using namespace std;typedef struct pnode{double x,y,d;}point; point P[ 10000 ];point S[ 10000 ];point MP;double crossproduct( point a, point b, point c )//ab到ac {return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}double dist( point a, point b ){return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));}bool cmp1( point a, point b ){if ( a.x == b.x ) return a.y < b.y;else return a.x < b.x;}bool cmp2( point a, point b ){return crossproduct( P[0], a, b ) < 0;}bool cmp3( point a, point b ){double cp = crossproduct( P[0], a, b );if ( cp == 0.0 ) {if ( !crossproduct( P[0], a, MP ) )//在回边上 return a.d > b.d;else return a.d < b.d;}else return cp < 0;}double Graham( int N ){sort( P+0, P+N, cmp1 );sort( P+1, P+N, cmp2 );//处理共线 for ( int i = 1 ; i < N ; ++ i )P[i].d = dist( P[0], P[i] );MP = P[N-1];sort( P+1, P+N, cmp3 );int top = -1;if ( N > 0 ) S[++ top] = P[0];if ( N > 1 ) S[++ top] = P[1];if ( N > 2 ) {S[++ top] = P[2];for ( int i = 3 ; i < N ; ++ i ) {while ( crossproduct( S[top-1], S[top], P[i] ) > 0 ) -- top;S[++ top] = P[i];}}S[++ top] = P[0];double L = 0.0;for ( int i = 0 ; i < top ; ++ i ) {L += dist( S[i], S[i+1] );printf("(%.1lf,%.1lf)-",S[i].x,S[i].y);}printf("(%.1lf,%.1lf)\n",S[0].x,S[0].y);printf("Perimeter length = %.2lf\n",L);return L;}int main(){int N,T = 1; while ( scanf("%d",&N) && N ) {for ( int i = 0 ; i < N ; ++ i )scanf("%lf%lf",&P[i].x,&P[i].y);if ( T > 1 ) printf("\n");printf("Region #%d:\n",T ++);Graham( N );}return 0;}

原创粉丝点击