NYOJ-----3---多边形重心问题

来源:互联网 发布:淘宝批量注册账号 编辑:程序博客网 时间:2024/05/22 05:13

多边形重心问题

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
描述
在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接),所有线段不和其他线段相交,但是可以重合,可得到一个多边形或一条线段或一个多边形和一个线段的连接后的图形;
如果是一条线段,我们定义面积为0,重心坐标为(0,0).现在求给出的点集组成的图形的面积和重心横纵坐标的和;
输入
第一行有一个整数0<n<11,表示有n组数据;
每组数据第一行有一个整数m<10000,表示有这个多边形有m个顶点;
输出
输出每个多边形的面积、重心横纵坐标的和,小数点后保留三位;
样例输入
330 10 20 331 10 00 141 10 00 0.50 1
样例输出
0.000 0.0000.500 1.0000.500 1.000
坐标系中三角形面积公式:((x1*y2 + x2*y3 + x3*y1)-(x2*y1 + x3*y2 + x1*y3))/ 2.0

推广至n边形面积得:S = ((x1*y2 + x2*y3 + x3*y1)-(x2*y1 + x3*y2 + x1*y3)+ (x1*y3 + x3*y4 + x4*y1)-(x3*y1 + x4*y3 + x1*y4)+ ……)/ 2.0

化简得:S = ((x1*y2 - x2*y1) + (x2*y3 - x3*y2) + …… + (xn*y1 - x1*yn))

三角形重心坐标为:x = (x1+x2+x3)/ 3.0                y = (y1+y2+y3)/ 3.0

但是不能直接推广到n边形重心,因为重心是重量的重心,重量随面积均匀分布,要将面积作为权值加入坐标才可以推广至n边形

即x = ((x1+x2)/ 3.0*S1 + (x2+x3)/ 3.0*S2 + ……)/ S

同理y = ((y1+y2)/ 3.0 *S1 + (y2+y3)/ 3.0*S2 + ……)/ S

#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set> #include<stack>#include<queue>#include<vector>#include<functional>#define PI acos(-1.0)#define INF 0x3f3f3f3f#define CL(a, b) memset(a, b, sizeof(a))using namespace std;typedef long long LL;const int maxn = 1e5+10;const int MOD = 1e9+7;double X[maxn], Y[maxn];int main(){int t, n;double area, s, xx, yy;scanf("%d", &t);while(t--){scanf("%d", &n);xx = yy = area = s = 0;for(int i = 0; i < n; i++) scanf("%lf%lf", &X[i], &Y[i]);for(int i = 1; i <= n; i++){area = (X[i-1]*Y[i%n] - X[i%n]*Y[i-1]) / 2.0;s += area;xx += area*(X[i%n] + X[i-1]) / 3.0;yy += area*(Y[i%n] + Y[i-1]) / 3.0; }s = fabs(s);//s小于1e-4可看做除数为0if(s < 1e-4) printf("0.000 0.000\n");else printf("%.3lf %.3lf\n", s, fabs(xx+yy)/s);}return 0;}

0 0
原创粉丝点击