凸包+多边形重心模板

来源:互联网 发布:张子萱淘宝店名字 编辑:程序博客网 时间:2024/05/22 05:32

本模板通过了HDU 3685

凸包模板是正确的,多边形求重心也是正确的,把两块板拼在一起莫名其妙地错了,唉

最后还是调出了,发现有一个函数返回类型本来应该是double,我把它写成int型了,WA了二十多发,醉了醉了。。。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<sstream>#include<fstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1using namespace std;const int maxn=1000005,inf=1<<29;const double eps = 1e-8;int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};int n,m,t;struct P{    double x,y;    P(){}    P(double x,double y):x(x),y(y){}    P operator + (P p)    {        return P(x+p.x,y+p.y);    }    P operator - (P p)    {        return P(x-p.x,y-p.y);    }    P operator *(double d)    {        return P(x*d,y*d);    }    double dot(P p)    {        return x*p.x+y*p.y;    }    double det(P p)    {        return x*p.y-y*p.x;    }}ps[maxn];//点的坐标存放在这里struct node{double x,y,area;}b[maxn];bool cmp(P a,P b){    if(a.x!=b.x) return a.x<b.x;    return a.y<b.y;}double area(P a,P b,P c)//求三角形面积{    return 0.5*fabs((b-a).det(c-a));}double area1(P a,P b,P c)//求三角形有向面积{    return 0.5*(b-a).det(c-a);}double ploy_area()//求多边形面积{    double ans=0.0;    for(int i=1;i<n-1;i++) ans+=area1(ps[i+1],ps[i],ps[0]);    return fabs(ans);}P Focus( ){//求多边形重心      double ans_x,ans_y;      double sum_Area=0;     int cnt=0;//被切割为三角形的个数     for( int i=2;i<n;i++ ){          double tmp=area1( ps[ i-1 ],ps[ i ],ps[ 0 ] );          b[ cnt ].x=ps[ 0 ].x+ps[ i-1 ].x+ps[ i ].x;          b[ cnt ].y=ps[ 0 ].y+ps[ i-1 ].y+ps[ i ].y;         b[ cnt ].area = tmp;          sum_Area += tmp;         cnt++;      }     ans_x=ans_y=0;      for( int i=0;i<cnt;i++ ){         ans_x+=b[ i ].x*b[ i ].area;         ans_y+=b[ i ].y*b[ i ].area;      }      ans_x/=(3.0*sum_Area);      ans_y/=(3.0*sum_Area);//重心坐标    P grav;     grav.x=ans_x,grav.y=ans_y;     return grav;//返回重心坐标  }vector<P> convex_hull(int n)//求凸包{    sort(ps,ps+n,cmp);    int k=0;    vector<P> qs(n*2);    for(int i=0;i<n;i++)    {        while(k>1&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;        qs[k++]=ps[i];    }    for(int i=n-2,t=k;i>=0;i--)    {        while(k>t&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;        qs[k++]=ps[i];    }    qs.resize(k-1);    return qs;}double dist(P a,P b)//求两个点之间的距离的平方{    //return (p-q).dot(p-q);    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}double dist1(P p,P q)//求两个点之间距离{    int t=(p-q).dot(p-q);    return sqrt(t*1.0);}bool judge( P a,P b,P now ){//判断会不会出现钝角    double dis1,dis2,dis3;   dis1 = dist( a,b );    dis2 = dist( a,now );    dis3 = dist( b,now );     if( (dis1+dis2-dis3>eps)&&(dis1+dis3-dis2>eps) )         return true;//这两个角必须为锐角,才可能保证 now 这个点在a,b“之间“     return false; }void solve(){    double x,y;    P center=Focus();//求出重心    vector<P> qs=convex_hull(n);//求凸包   //qs.push_back(qs[0]);    int cnt=0;    for(int i=1;i<qs.size();i++)        if(judge(qs[i-1],qs[i],center)) cnt++;    if(judge(qs[qs.size()-1],qs[0],center)) cnt++;    printf("%d\n",cnt);    //printf("%.2lf %.2lf\n",center.x,center.y);}int main(){   //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=0;i<n;i++) scanf("%lf%lf",&ps[i].x,&ps[i].y);        solve();    }    return 0;}


0 0
原创粉丝点击