题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=3
题目大意是,有n个点,第i个和第i+1个相连接,第1个和第n歌想链接,问链接图形的重心坐标的横纵坐标和,and面积;
/********************************************/
计算几何题
先用相临的两点和0 . 0 练成三角形,然后算出面积,用叉积,注意有负有正,所以可以消去多余的重合部分,
然后每个三角形的面积再乘上三个点的坐标之和的三分之一记为f(分别对x和y) ,就为面积在此区域的积分,然后把各个三角形面积相加,就得到总面积,此时注意正负问题,因为如果去点按照逆时针为正,顺时针为负,所以得取绝对值,但是取绝对值前先求出重心横纵坐标的和,为刚才所求的f除以面积,因为可能有负的情况。
代码如下:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
struct mpoint
{
double x;
double y;
}p[10001];
int n;
double getarea(mpoint p1,mpoint p2) //求出点(0,0),p1,p2围城三角形的面积。(有负的可能)
{
double ans;
ans=p1.x*p2.y-p1.y*p2.x;
return ans/2;
}
void execute()
{
double res=0;
double x,y;
x=0;
y=0;
double t;
for(int i=0;i<n;i++)//每个i和i之后的那个点和点(0,0)都围城一个三角形(可能为一线段)
{
t=getarea(p[i],p[i+1]);
res+=t;
x+=t*(p[i].x+p[i+1].x)/3;
y+=t*(p[i].y+p[i+1].y)/3;
}
double point=(x+y)/res;
res=fabs(res);
if(fabs(res)<=0.000001)
cout<<"0.000 0.000"<<endl;
else
cout<<fixed<<setprecision(3)<<res<<' '<<point<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=0;i<n;i++)
cin>>p[i].x>>p[i].y;
p[n].x=p[0].x; //最后一个点是和第一个点相连接的,为了一会求面积,把第n+1个点的值赋成第1个点的值
p[n].y=p[0].y;
execute();
}
return 0;
}