int abs(int i); // 处理int类型的取绝对值
double fabs(double i); //处理double类型的取绝对值
float fabsf(float i); /处理float类型的取绝对值
多边形重心问题
链接:click here
时间限制:3000 ms | 内存限制:65535
难度:5
描述
在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接),所有线段不和其他线段相交,但是可以重合,可得到一个多边形或一条线段或一个多边形和一个线段的连接后的图形;
如果是一条线段,我们定义面积为0,重心坐标为(0,0).现在求给出的点集组成的图形的面积和重心横纵坐标的和;
输入
第一行有一个整数0<n<11,表示有n组数据;
每组数据第一行有一个整数m<10000,表示有这个多边形有m个顶点;
输出
输出每个多边形的面积、重心横纵坐标的和,小数点后保留三位;
样例输入
3
3
0 1
0 2
0 3
3
1 1
0 0
0 1
4
1 1
0 0
0 0.5
0 1
样例输出
0.000 0.000
0.500 1.000
0.500 1.000
代码:
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{0,-1},{-1,0},{0,1},{1,0}};
const double Pi = acos(-1.0);
const double EPS = 1e-10;
struct Point
{
double x,y;
};
//叉积求面积
double Area(const Point p0,const Point p1,const Point p2)
{
// 另外在求解的过程中,不需要考虑点的输入顺序是顺时针还是逆时针,相除后就抵消了。
return (p0.x*p1.y+p1.x*p2.y+p2.x*p0.y-p1.x*p0.y-p2.x*p1.y-p0.x*p2.y)/2.0;
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
Point p0,p1,p2;
double area = 0,suma = 0,sumx = 0,sumy = 0;
scanf("%d",&n);
scanf("%lf%lf",&p0.x,&p0.y);
scanf("%lf%lf",&p1.x,&p1.y);
for(int i = 2; i < n; ++i)
{
scanf("%lf%lf",&p2.x,&p2.y);
area = Area(p0,p1,p2);
suma += area;
sumx += (p0.x+p1.x+p2.x)*area;
sumy += (p0.y+p1.y+p2.y)*area;
p1 = p2;
}
if(fabs(suma) <= EPS)
{
printf("0.000 0.000\n");
continue;
}
printf("%.3lf %.3lf\n",fabs(suma),(sumx+sumy)/suma/3.0);
}
return 0;
}