不多说...凸包网上解法很多,这个是用graham的极角排序,也就是算导上的那个解法
其实其他方法随便乱搞都行...我只是测一下模板...
struct POINT{ double x,y; POINT(double _x = 0, double _y = 0):x(_x),y(_y){};};POINT p[MAXN],s[MAXN];double dist(POINT p1,POINT p2){ return(sqrt((p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y)));}double multiply(POINT sp,POINT ep,POINT op){ return (sp.x-op.x) * (ep.y-op.y) - (ep.x-op.x) * (sp.y-op.y);}bool ptcmp(POINT a,POINT b){ // 极角排序cmp p[]为全局变量 if(multiply(a,b,p[0]) == 0) return dist(p[0],a) < dist(p[0],b); return (multiply(a,b,p[0]) > 0);}int Graham_scan(POINT p[],POINT s[],int n){ // 返回凸包点的个数 int i,k = 0,top = 2; for(i = 1; i < n ; i++) // 取y最小且x最小的点为凸包起点 if((p[i].y < p[k].y) || ((p[i].y == p[k].y) && (p[i].x < p[k].x))) k = i; swap(p[0],p[k]); // 起点设置为p[0] sort(p+1,p+n,ptcmp); // 极角排序 for(i = 0 ; i < 3 ; i++) s[i] = p[i]; // 前三个点入栈 for(i = 3; i < n ; i++){ while(multiply(p[i],s[top],s[top-1]) >= 0) top--; s[++top] = p[i]; } return top + 1;}int main(){ int a,b,n; double r; while(~scanf("%d%lf",&n,&r)){ for(int i = 0 ; i < n ; i++) scanf("%lf%lf",&p[i].x,&p[i].y); int len = Graham_scan(p,s,n); double sum = dist(s[len-1],s[0]); for(int i = 0 ; i < len-1 ; i++){ sum += dist(s[i],s[i+1]); } sum += (PI*r*2); cout<<