多边形重心

//其实不得不说这个问题的求解过程还挺麻烦的,我用的C++中简单的写法,没有调用复杂的函数;后边有最后的最优程序。

多边形重心问题

时间限制:3000 ms  |  内存限制:65535 KB

难度: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

 

公式S=(1/2)*(x1y2*1+x2y3*1+x3y1*1-x1y3*1-x2y1*1-x3y2*1)

我的程序

#include <iostream>

#include <stdio.h>

#define M 10000

using namespace std;

int main()

{int n; int i,j;  int m;  

 float a[11][M][2];

 float x,y;

 float s;  float Sum;//面积

 cin>>n;

 //求面积和重心

 for(i=1;i<=n;i++)

 {s=0; Sum=0;x=0;y=0;

  cin>>m;

     for(j=1;j<=m;j++)               //输入

     cin>>a[i][j][0]>>a[i][j][1];

 for(int p=3;p<=m;p++)  {s=((a[i][p-1][0]-a[i][1][0])*(a[i][p][1]-a[i][1][1])-(a[i][p][0]-a[i][1][0])*(a[i][p-1][1]-a[i][1][1]))/2;

  x+=(a[i][1][0]+a[i][p][0]+a[i][p-1][0])/3*s;  

  y+=(a[i][1][1]+a[i][p][1]+a[i][p-1][1])/3*s;

 Sum+=s;

 }

 if(Sum==0)    printf("0.000 0.000\n");  

 else          printf("%0.3lf %0.3lf\n",-Sum,(x+y)/Sum);  

 }

return 0;

}

最优程序: 

#include <stdio.h>

#include <math.h>

inline double g(double x1,double y1,double x2,double y2,double x3,double y3) {  return (x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2)/2; } int main() {   int n,m;  scanf("%i",&n);   while(n--){ scanf("%i",&m); m-=2;   double x1,y1,x,y,xn,yn,gsx=0,gsy=0,s=0,cs=0;   scanf("%lf%lf%lf%lf",&x1,&y1,&x,&y); while(m--)   {    scanf("%lf%lf",&xn,&yn);    s+=(cs=g(x1,y1,x,y,xn,yn));    gsx+=(x1+x+xn)*cs/3;    gsy+=(y1+y+yn)*cs/3;    x=xn;    y=yn; }   printf("%.3f %.3f\n",fabsf(s),(s==0?0.0:fabsf((gsx+gsy)/s)));  } }    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello689

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值