Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4819 Accepted Submission(s): 2006
1 #include <iostream>
2 #include <iomanip>
3 using namespace std; 4 struct point { double x, y; }; 5 point bcenter(point pnt[], int n){ 6 point p, s; 7 double tp, area = 0, tpx = 0, tpy = 0; 8 p.x = pnt[0].x; p.y = pnt[0].y; 9 for (int i = 1; i <= n; ++i) { // point: 0 ~ n-1
10 s.x = pnt[(i == n) ? 0 : i].x; 11 s.y = pnt[(i == n) ? 0 : i].y; 12 tp = (p.x * s.y - s.x * p.y); area += tp / 2; 13 tpx += (p.x + s.x) * tp; tpy += (p.y + s.y) * tp; 14 p.x = s.x; p.y = s.y; 15 } 16 s.x = tpx / (6 * area); s.y = tpy / (6 * area); 17 return s; 18 } 19 point P[1000000]; 20 int main() 21 { 22 int T,N; 23 cin>>T; 24 cout<<setiosflags(ios::fixed)<<setprecision(2); 25 while(T--){ 26 cin>>N; 27 for(int i=0;i<N;i++) //从0开始输入多边形的n个点
28 cin>>P[i].x>>P[i].y; 29 point t = bcenter(P,N); //返回重心坐标
30 cout<<t.x<<' '<<t.y<<endl; 31 } 32 return 0; 33 }
重新做了一遍这个题,现在理解了求多边形重心的算法,在poj上找到了一样的题,在两个OJ上同时提交。一开始总是WA,后来看了很多题解和讨论发现是精度问题,由于除法会产生很大的误差,再小的浮点误差,累积到10w后都是很大的误差,所以应该尽量减少除法。我改进之后,算法只有加法和乘法,只有最后再/3。最后在hdu上AC,但是poj上死活AC不了,而且上面使用模板的代码放到poj上竟然超时,百思不得其解。郁闷……
hdu上AC的代码:
1 #include <stdio.h>
2 typedef struct { 3 double x,y; 4 }Point; 5 double getS(Point a,Point b,Point c) //返回三角形面积
6 { 7 return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y)*(c.x - a.x))/2; 8 } 9 Point getPZ(Point p[],int n) //返回多边形重心
10 { 11 Point z; 12 double sumx = 0,sumy = 0; 13 double sumS = 0; 14 for(int i=2;i<=n-1;i++){ 15 double S = getS(p[1],p[i+1],p[i]); 16 sumS += S; 17 sumx += (p[1].x+p[i].x+p[i+1].x)*S; 18 sumy += (p[1].y+p[i].y+p[i+1].y)*S; 19 } 20 z.x = sumx / (sumS*3 ); 21 z.y = sumy / (sumS*3 ); 22 return z; 23 } 24 Point p[1000001]; 25 int main() 26 { 27 int T; 28 scanf("%d",&T); 29 while(T--){ 30 int n; 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++) 33 scanf("%lf%lf",&p[i].x,&p[i].y); 34 Point z = getPZ(p,n); 35 printf("%.2lf %.2lf\n",z.x,z.y); 36 } 37 return 0; 38 }
Freecode : www.cnblogs.com/yym2013