HDU 1115 (平面几何 重心)

来源:互联网 发布:高正软件 编辑:程序博客网 时间:2024/04/29 17:52

用重心公式 x0 =  Σ(xi*mi)/m, y0 = Σ(yi*mi)/m,其中mi用有向三角形的面积表示,也就是叉积的一半。

#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>using namespace std;typedef unsigned long long ll;#define maxn 111const double eps = 1e-10;int dcmp (double x) {//控制精度    if (fabs (x) < eps)        return 0;    else return x < 0 ? -1 : 1;}#define pi acos(-1)//***********点,向量struct point {    double x, y;    point (double _x = 0, double _y = 0) : x(_x), y(_y) {}    point operator - (const point a) const {//向量相减        return point (x-a.x, y-a.y);    }    point operator + (const point a) const {//向量相加    return point (x+a.x, y+a.y);    }    bool operator < (const point &a) const {        return x < a.x || (dcmp (x - a.x) == 0 && y < a.y);    }    bool operator == (const point &a) const {//判断两个点相等    return dcmp (x-a.x) == 0 && dcmp (y-a.y) == 0;    }    point operator * (const double &a) {//向量乘一个数    return point (a*x, a*y);   }   point operator / (const double &b) {//向量除一个数   return point (x/b, y/b);   }};double rad_degree (double rad) {//弧度转化为角度return rad/pi*180;}double degree_rad (double degree) {//角度转化为弧度return degree/180*pi;}double cross (point a, point b) {//叉积    return a.x*b.y-a.y*b.x;}double dot (point a, point b) {//点积    return a.x*b.x + a.y*b.y;}double length (point a) {//向量的模return sqrt (dot (a, a));}double angle (point a, point b) {//两个向量的夹角return acos (dot (a, b) / length (a) / length (b));}point rotate (point a, double rad) {//向量旋转rad角(弧度制)return point (a.x*cos (rad)-a.y*sin (rad), a.x*sin (rad)+a.y*cos (rad));}point nomal (point a) {//单位法向量 //如果是零向量 就返回零向量 if (dcmp (a.x) == 0 && dcmp (a.y) == 0) {return point (0, 0);}double l = length (a);return point (-a.y/l, a.x/l);}point GetLineIntersection (point p, point v, point q, point w) {//获取直线交点//直线A上的点 直线A的方向向量 直线B上的点 直线B的方向向量//使用前判断两直线有唯一焦点 当且仅当 corss(v, w)!=0point u = p-q;double t = cross (w, u) / cross (v, w);return p+v*t;}double DistanceToLine (point p, point a, point b) {//点到直线的距离//点p到直线ab的距离point v1 = b-a, v2 = p-a;return fabs (cross (v1, v2) / length (v1));//不加绝对值得到的是有向距离}double DistanceToRay (point p, point a, point b) {//点到射线的距离//点p到射线a,a是射线的端点,b是射线的方向向量point v = a-p;if (dot (v, b) >= 0) return length (v);else return DistanceToLine (p, a, b);}double DistanceToSegment (point p, point a, point b) {//点到线段的距离//点p到线段ab的距离point v1 = b-a, v2 = p-a, v3 = p-b;if (dcmp (dot (v1, v2)) < 0) return length (v2);else if (dcmp (dot (v1, v3)) > 0) return length (v3);else return fabs (cross (v1, v2)) / length (v1);}point GetLineProjection (point p, point a, point b) {//点在直线上的投影//点p在直线ab上的投影点point v = b-a;return a + v*(dot (v, p-a) / dot (v, v));}bool SegmentProperIntersection (point a1, point a2, point b1, point b2) {//判断线段规范相交(交点不在端点)double c1 = cross (a2-a1, b1-a1), c2 = cross (a2-a1, b2-a1),c3 = cross (b2-b1, a1-b1), c4 = cross (b2-b1, a2-b1);return dcmp (c1) * dcmp (c2) < 0 && dcmp (c3)*dcmp (c4) < 0;}bool PointOnSegment (point p, point a1, point a2) {//判断点p是不是在线段a1a2上    if (dcmp (cross (a1-p, a2-p)) == 0 && dcmp (dot (a1-p, a2-p)) <= 0)    //改成小于号表示交点不在端点上        return 1;    return 0;}bool SegmentIntersection (point a1, point a2, point b1, point b2) {//判断线段有交点if (PointOnSegment (a1, b1, b2) || PointOnSegment (a2, b1, b2) || PointOnSegment (b1, a1, a2) || PointOnSegment (b2, a1, a2))return 1;if (SegmentProperIntersection (a1, a2, b1, b2))return 1;return 0;} double PolygonArea (point *p, int n) {//多边形的有向面积,加上绝对值就是面积//n个点double area = 0;for (int i = 1; i < n-1; i++) {area += cross (p[i]-p[0], p[i+1]-p[0]);}return area/2;}bool PointInPolygon (point a, point *b, int n) {//判断点在多边内部(凸凹都可以)//点a 多边形数组b 多边形n个点    int w = 0;    for (int i = 0; i < n; i++) {        if (PointOnSegment (a, b[i], b[(i+1)%n]))            return 0;        int k = dcmp (cross (b[(i+1)%n]-b[i], a-b[i]));        int d1 = dcmp (b[i].y - a.y);        int d2 = dcmp (b[(i+1)%n].y - a.y);        if (k > 0 && d1 <= 0 && d2 > 0)            w++;        if (k < 0 && d2 <= 0 && d1 > 0)            w--;    }    if (w != 0)        return 1;    return 0;}point centre_of_gravity (point *p, int n) {//多边形的重心(凹凸都可以)double sum = 0.0, sumx = 0, sumy = 0;  point p1 = p[0], p2 = p[1], p3;    for (int i = 2; i <= n-1; i++) {          //scanf ("%lf%lf", &p3.x, &p3.y);          p3 = p[i];        double area = cross (p2-p1, p3-p2)/2.0;          sum += area;          sumx += (p1.x+p2.x+p3.x)*area;          sumy += (p1.y+p2.y+p3.y)*area;          p2 = p3;      }      return point (sumx/(3.0*sum), sumy/(3.0*sum));}point p[1111111];int n;int main () {int t;cin >> t;while (t--) {cin >> n;for (int i = 0; i < n; i++) {cin >> p[i].x >> p[i].y;}point ans = centre_of_gravity (p, n);printf ("%.2f %.2f\n", ans.x+eps, ans.y+eps);}    return 0;}

0 0
原创粉丝点击