HDU1115 Lifting the Stone

HDU1115 Lifting the Stone

题意

求n个点的多边形的重心。\(3 \leq n \leq 1000000\)

题解

1.如果是平面上若干个离散的带权点的话,就能轻松算出重心了。公式:
\(X=(x1*m1+x2*m2+...+xn*mn)/(m1+m2+...+mn)\);
\(Y=(y1*m1+y2*m2+...+yn*mn)/(m1+m2+...+mn)\)
2.考虑把多边形转化成上面的形式,以第一个点为极点,然后和其余每相邻两个点求一次三角形有向面积以及三角形重心。
3.把这些三角形的重心当成离散的点,把对应三角形有向面积当成点的权值,就转化成了1的模型了。

\(Code\)

#include <bits/stdc++.h>
#define LL long long
#define LD double
using namespace std;
const int N=3e5+10;
const LD eps=1e-2;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void print(LL x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

int n;

struct P{
    LD x,y;
    P(LD xx=0,LD yy=0){x=xx;y=yy;} 
};

P operator - (P x,P y){return P(x.x-y.x,x.y-y.y);}
P operator + (P x,P y){return P(x.x+y.x,x.y+y.y);}
LD operator * (P x,P y){return x.x*y.y-x.y*y.x;} 

P a,b,c,d;

int main(){
    int T;scanf("%d",&T);
    LD X,Y,M,w;
    while(T--){
        scanf("%d",&n);
        X=0;Y=0;M=0;
        a.x=read();a.y=read();
        b.x=read();b.y=read();
        for(int i=3;i<=n;++i){
            c.x=read();c.y=read();
            d=a+b+c;d.x=d.x/(LD)3;d.y=d.y/(LD)3;
            w=(c-a)*(b-a);
            M+=w;X+=w*d.x;Y+=w*d.y;
            b=c;
        }
        X=X/M;
        Y=Y/M;
        if(abs(X)<eps) X=0;
        if(abs(Y)<eps) Y=0;
        printf("%0.2lf %0.2lf\n",X,Y);
    }
    return 0;
}


posted @ 2020-10-22 11:32  Iscream-2001  阅读(93)  评论(0编辑  收藏  举报
/* */ /* */