水题。
顺时针输出凸包的点,求出凸包边长的总长度。
经测试,不存在n = 1的情况。也没说具体有多少个点。。。这题真是的。。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> using namespace std; const int MAX = 120000; const double eps = 1e-6; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y struct point{ double x,y; }; point c[MAX]; double disp2p(point a,point b) { return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) ); } 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) // 排序 { double len = crossProduct(c[0],a,b); if( dd(len,0.0) ) return xy(disp2p(c[0],a),disp2p(c[0],b)); return xy(len,0.0); } int stk[MAX]; int top; void Graham(int n) { int tmp = 0; for(int i=1; i<n; i++) if( xy(c[i].x,c[tmp].x) || dd(c[i].x,c[tmp].x) && xy(c[i].y,c[tmp].y) ) tmp = i; swap(c[0],c[tmp]); sort(c+1,c+n,cmp); stk[0] = 0; stk[1] = 1; top = 1; for(int i=2; i<n; i++) { while( xyd( crossProduct(c[stk[top]],c[stk[top-1]],c[i]), 0.0 ) && top >= 1 ) top--; stk[++top] = i; } double sum = 0.0; for(int i=0; i<=top; i++) sum += disp2p(c[stk[i]],c[stk[(i+1)%(top+1)]]); printf("(%.1lf,%.1lf)-",c[stk[0]].x,c[stk[0]].y); for(int i=top; i>0; i--) printf("(%.1lf,%.1lf)-",c[stk[i]].x,c[stk[i]].y); printf("(%.1lf,%.1lf)/n",c[stk[0]].x,c[stk[0]].y); printf("Perimeter length = %.2lf/n",sum); } int main() { int n; int ncases = 1; while( ~scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf%lf",&c[i].x,&c[i].y); printf("Region #%d:/n",ncases++); Graham(n); } return 0; }