Cod sursa(job #1723990)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 1 iulie 2016 23:27:01
Problema Rubarba Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <fstream>
#include <cmath>
#include <limits>
#include <cmath>

using namespace std;

#define double long double

constexpr int MAX_N = 100000;
constexpr double EPS = 1e-17;

class Plane {
private:
    class Point {
    private:
        double x, y;
    public:

        Point() : x(.0), y(.0) {
        }

        Point(const double _x, const double _y) : x(_x), y(_y) {
        }

        double getAbscissa() const {
            return x;
        }

        double getOrdinate() const {
            return y;
        }

        void m_rotate(const double m_cos, const double m_sin) {
            double new_x = (this->x) * m_cos - (this->y) * m_sin,
                   new_y = (this->x) * m_sin + (this->y) * m_cos;
            this->x = new_x; this->y = new_y;
        }

        friend ifstream &operator >>(ifstream &fin, Point &A) {
            int _x, _y; fin >> _x >> _y;
            A.x = _x; A.y = _y;
            return fin;
        }
    };
    Point V[MAX_N];
    int n;

public:
    Plane() : n(0) {
    }

    Plane(const int m_size) : n(m_size) {
    }

    void m_resize(const int new_size) {
        n = new_size;
    }

    friend ifstream &operator >>(ifstream &fin, Plane &A) {
        for (int i = 0; i < A.n; i += 1) {
            fin >> A.V[i];
        }
        return fin;
    }

    void m_rotate(const double m_cos, const double m_sin) {
        for (int i = 0; i < this->n; i += 1) {
            (this)->V[i].m_rotate(m_cos, m_sin);
        }
    }

    double retangleArea() const {
        double min_x, max_x, min_y, max_y;

        min_x = max_x = V[0].getAbscissa();
        min_y = max_y = V[0].getOrdinate();

        for (int i = 1; i < n; i += 1) {
            if (V[i].getAbscissa() < min_x) {
                min_x = V[i].getAbscissa();
            } else if (V[i].getAbscissa() > max_x) {
                max_x = V[i].getAbscissa();
            }
            if (V[i].getOrdinate() < min_y) {
                min_y = V[i].getOrdinate();
            } else if (V[i].getOrdinate() > max_y) {
                max_y = V[i].getOrdinate();
            }
        }

        return (max_x - min_x) * (max_y - min_y);
    }

    double rotatePlane(const double radians) {
        m_rotate(cos(radians), sin(radians));
        const double answer = retangleArea();
        m_rotate(cos(-radians), sin(-radians));
        return answer;
    }

    double ternarySearch() {
        double lo = .0, hi = 3 * asin(.5);
        while (hi - lo > EPS) {
            const double mid = (lo + hi) * .5;
            if (rotatePlane(mid) > rotatePlane(mid + EPS)) {
                lo = mid;
            } else {
                hi = mid;
            }
        }
        return lo;
    }
};

Plane garden;

int main() {
    ifstream fin("rubarba.in");
    ofstream fout("rubarba.out");
    fin.tie(0);
    ios_base::sync_with_stdio(false);

    int m_size; fin >> m_size;
    garden.m_resize(m_size);
    fin >> garden;

    fout.setf(ios::fixed, ios::floatfield);
    fout.precision(2);
    fout << garden.rotatePlane(garden.ternarySearch()) << '\n';
    fout.close();
    return 0;
}