多边形重心问题
时间限制:
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
-
思路:将多变形分割成三角形再进行计算。
-
参考资料:三角形面积:点击打开链接
-
多边形重心:点击打开链接
-
结果位数保留:点击打开链接
-
代码一(原创)如下:
-
代码二(引用于:点击打开链接)#include<iostream> #include<cmath> #include<iomanip> using namespace std; int n,m; double *price; void cal(){ //求取横坐标 double area=0.0,x=0.0,y=0.0; for(int i=0;i<(m-2);i++){ //分割成三角形求取面积 double temp=0.0; double x1=price[0];//固定点 double y1=price[1]; double x2=price[2+i*2];//随着i增涨的亮边 double y2=price[3+i*2]; double x3=price[4+i*2]; double y3=price[5+i*2]; //double temp=0.5*abs(x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2); temp=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/2; area+=temp; x+=(x1+x2+x3)*temp/3.0; y+=(y1+y2+y3)*temp/3.0; } if(fabs(area-0)<0.0000001) cout<<"0.000 0.000"<<endl; else cout<<setiosflags(ios::fixed)<<setprecision(3)<<fabs(area) <<" " <<setiosflags(ios::fixed)<<setprecision(3)<<(x/area+y/area) <<endl; } int main(){ cin>>n;//输入要运算的组数 while(n--){ cin>>m; price=new double[m*2]; for(int i=0;i<m*2;i++){ cin>>price[i];//全部放入一个一维数组 } cal(); delete []price; } return 0; }
-
代码三(引用于:点击打开链接)#include<iostream> #include<cmath> #include<cstdio> using namespace std; struct Point{ double x,y; }; int main() { int n,t; scanf("%d",&t); while(t--){ scanf("%d",&n); Point p1,p2,p3; double gx,gy,sumarea; gx=gy=sumarea=0; scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y); for(int i=2;i<n;i++){ scanf("%lf%lf",&p3.x,&p3.y); double area=((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))/2; gx+=(p1.x+p2.x+p3.x)*area; gy+=(p1.y+p2.y+p3.y)*area; sumarea+=area; p2=p3; } gx=gx/sumarea/3; gy=gy/sumarea/3; if(fabs(sumarea - 0) < 0.0000001)puts("0.000 0.000"); else printf("%.3lf %.3lf\n",fabs(sumarea),gy+gx); } return 0; }
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0.0000001 const int N = 10010; struct point{ double x, y; point():x(0),y(0){} }p[N]; int main(){ int ncase; scanf("%d", &ncase); while(ncase--){ int n; double result = 0; point ans; scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%lf%lf", &p[i].x, &p[i].y); for(int i = 1; i <= n; ++i){ double temp = (p[i % n].x * p[i -1].y - p[i % n].y * p[i -1].x) / 2.0; result += temp; ans.x += temp * (p[i % n].x + p[i - 1].x) / 3.0; ans.y += temp * (p[i % n].y + p[i - 1].y) / 3.0; } if(fabs(result - 0) < INF) puts("0.000 0.000"); else printf("%.3lf %.3lf\n", fabs(result), (ans.x + ans.y) / result); //result取绝对值 } return 0; } /* 1 7 2 3 4 5 3 4 7 8 4 78 34 56 8 100 */
(全文完)
-
第一行有一个整数0<n<11,表示有n组数据;