求凸包的周长,模板题,卡了很久,最后发现是如果n=2的时候没有特判

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1050;
struct Point{
   
    int x,y;
}p[N],s[N];
int top,n;
int cross(Point a,Point b,Point c){
   
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dis(Point a,Point b){
   
    return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(Point a,Point b){
   
    int t=cross(p[0],a,b);
    if(t>0 || t==0 && dis(p[0],a)<dis(p[0],b)){
   
        return true;
    }else{
   
        return false;
    }
}
void init(int n){
   
    scanf("%d%d",&p[0].x,&p[0].y);
    Point p0=Point{
   p[0].x,p[0].y};
    int k=0;
    for(int i=1;i<n;i++){
   
        scanf("%d%d",&p[i].x,&p[i].y);
        if(p[i].y<p0.y || p[i].y==p0.y && p[i].x<p0.x){
   
            p0=Point{
   p[i].x,p[i].y};
            k=i;
        }
    }
    p[k]=p[0];
    p[0]=p0;
    sort(p+1,p+n,cmp);
}
void graham(int n){
   
    if(n==1){
   
        top=0;
        s[0]=p[0];
    }else if(n==2){
   
        top=1;
        s[0]=p[0];
        s[1]=p[1];
    }else{
   
        top=1;
        s[0]=p[0];
        s[1]=p[1];
        for(int i=2;i<n;i++){
   
            while(top>0 && cross(s[top-1],s[top],p[i])<=0){
   
                top--;
            }
            s[++top]=p[i];
        }
    }
}
int main(void){
   
    while(~scanf("%d",&n) && n){
   
        init(n);
        graham(n);
        //printf("%d\n",top);
        double ans=0;
        for(int i=1;i<=top;i++){
   
            ans+=dis(s[i],s[i-1]);
            //printf("%d %d %d %d %lf\n",s[i].x,s[i].y,s[i-1].x,s[i-1].y,dis(s[i],s[i-1]));
        }
        ans+=dis(s[0],s[top]);
        if(n==2){
   
            ans/=2;
        }
        printf("%.2lf\n",ans);
    }
    return 0;
}