1. 程式人生 > 實用技巧 >HDU1115 Lifting the Stone

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;
}