Skip to content

Instantly share code, notes, and snippets.

@erickguan
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save erickguan/b4f58e00cea8e417fee4 to your computer and use it in GitHub Desktop.

Select an option

Save erickguan/b4f58e00cea8e417fee4 to your computer and use it in GitHub Desktop.
UVa 10002
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
const double eps = 1e-8;
int cmp(double x) {
if (fabs(x) < eps) return 0;
if (x > 0) return 1;
return -1;
}
struct Point {
double x, y;
Point() {}
Point(double a, double b): x(a), y(b) {}
Point operator+(const Point &rhs)
{
return Point(x + rhs.x, y + rhs.y);
}
Point operator-(const Point &rhs) const
{
return Point(x - rhs.x, y - rhs.y);
}
bool operator==(const Point &rhs) const
{
return cmp(x - rhs.x) == 0 && cmp(y - rhs.y) == 0;
}
double operator^(const Point &rhs) const
{
return x * rhs.y - y * rhs.x;
}
};
class Solver {
public:
Solver(const vector<Point> &P): points(P) {}
void run(void);
private:
double cross(const Point &O, const Point &A, const Point &B)
{
return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}
double Area(void)
{
double sum = 0.0;
for (int i = 0; i < points.size() - 1; ++i) {
sum += (points[i] ^ points[i + 1]);
}
return sum / 2.0;
}
void ComputeConvexHull(void);
Point ComputeCenter(void);
vector<Point> points;
};
bool ComparePoints(const Point &a, const Point &b)
{
return cmp(a.x - b.x) < 0 || (cmp(a.x - b.x) == 0 && a.y < b.y);
}
void Solver::ComputeConvexHull()
{
int n = points.size();
vector<Point> convex_hull(2 * n);
sort(points.begin(), points.end(), ComparePoints);
points.erase(unique(points.begin(), points.end()), points.end());
int k = 0;
for (int i = 0; i < n; i++) {
while (k >= 2 && cross(convex_hull[k - 2],
convex_hull[k - 1],
points[i]) <= eps)
--k;
convex_hull[k++] = points[i];
}
int t = k + 1;
for (int i = n - 2; i >= 0; i--) {
while (k >= t && cross(convex_hull[k - 2],
convex_hull[k - 1],
points[i]) <= eps)
--k;
convex_hull[k++] = points[i];
}
points.assign(convex_hull.begin(), convex_hull.begin() + k - 1);
}
Point Solver::ComputeCenter()
{
vector<Point> p(points);
Point ans;
double area = 0.0, tmp;
ans.x = ans.y = 0.0;
for (int i = 1; i < p.size() - 1; i++)
{
tmp = cross(p[i], p[0], p[i + 1]) / 2.0;
ans.x += (p[0].x + p[i].x + p[i + 1].x) * tmp;
ans.y += (p[0].y + p[i].y + p[i + 1].y) * tmp;
area += tmp;
}
ans.x /= (3 * area);
ans.y /= (3 * area);
return ans;
}
void Solver::run()
{
ComputeConvexHull();
Point p = ComputeCenter();
printf("%.3lf %.3lf\n", p.x, p.y);
}
int main()
{
int N;
while (scanf("%d", &N) && N >= 3) {
vector<Point> p;
double x, y;
for (int i = 0; i < N; ++i) {
scanf("%lf%lf", &x, &y);
p.push_back(Point(x, y));
}
Solver s(p);
s.run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment