poj 1385 Lifting the Stone

题意:给出n个按构成简单多边形顺序的点,求出多边形的重心

简单多边形重心:sum(各个三角形重心 * 三角形有向面积权重)

各个三角形如图所示:
 

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#define MAX 1005
#include <complex>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <string>
#define INF 1e8
#define MAX (int)1e6+ 5
using namespace std;

struct Point
{
    double x, y;
    Point(){}
    Point(const double &x, const double &y):x(x), y(y){}
    Point operator + (const Point &b)const{
        return  Point(x + b.x, y + b.y);
    }
    Point operator / (const double&b)const{
        return  Point(x / b, y / b);
    }
    Point operator * (const double&b)const{
        return  Point(x * b, y * b);
    }
    friend double dot(const Point &a, const Point &b){
        return a.x * b.x + a.y * b.y;
    }
    friend double det(const Point &a, const Point &b){
        return a.x * b.y - a.y * b.x;
    }
    void in(){
        scanf("%lf %lf", &x, &y);
    }
    void out(){
        printf("%.2f %.2f\n", x, y);
    }
};
inline int next(const int &i, const int &n){ return (i + 1) % n;}
//该简单多变性按构成多边形的顺序给出点。
struct Polygon
{
    vector<Point>p;
    Polygon(){}
    Polygon(const vector<Point>pp):p(pp){}
    //有向面积和,有可能为负,绝对值为多边形面积
    double area(){
        int n = p.size(), ni;
        double ans  = 0;
        for(int i = 0; i < n; i++ ){
            ni  = next(i, n);
            ans += det(p[i], p[ni]);    //逆时针
        }
        return ans / 2;
    }
    //取每个三角形的中心, 以有向面积作为权重, 他们的和就是重心
    Point massCenter(){
        Point center(0, 0);
        int n = p.size(), ni;
        for(int i = 0; i < n; i++){
            ni = next(i, n);
            center = center + (p[i] + p[ni]) * det(p[i], p[ni]);//逆时针
        }
        return center / area() / 6;
    }
};
int T, n;
int main()
{
    cin>>T;
    double x, y;
    while(T--){
        cin>>n;
        vector<Point>p;
        for(int i = 0; i < n; i++){
            scanf("%lf %lf", &x, &y);
            p.push_back(Point(x, y));
        }
        Polygon(p).massCenter().out();
    }
    return 0;
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值