Cod sursa(job #2779906)

Utilizator EckchartZgarcea Robert-Andrei Eckchart Data 5 octombrie 2021 14:11:54
Problema Reuniune Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using pd = pair<double, double>;
using pld = pair<ld, ld>;
// #define LOCAL
#ifdef LOCAL
ifstream cin("input.txt");
ofstream cout("output2.txt");
#else
ifstream cin("reuniune.in");
ofstream cout("reuniune.out");
#endif
#define cin ::cin
#define cout ::cout


class Rectangle
{
private:
    ll x0, y0, x1, y1;

public:
    Rectangle() : x0{}, y0{}, x1{}, y1{} {};
    Rectangle(const ll _x0, const ll _y0, const ll _x1, const ll _y1) : x0{_x0}, y0{_y0}, x1{_x1}, y1{_y1} {};
    friend ifstream &operator>>(ifstream &is, Rectangle &rect)
    {
        is >> rect.x0 >> rect.y0 >> rect.x1 >> rect.y1;
        return is;
    }
    inline void set_intersection(const Rectangle &other)
    {
        this->x0 = max(this->x0, other.x0);
        this->y0 = max(this->y0, other.y0);
        this->x1 = min(this->x1, other.x1);
        this->y1 = min(this->y1, other.y1);
        if (this->x1 < this->x0 || this->y1 < this->y0)
        {
            *this = {0, 0, 0, 0};
        }
    }
    inline ll get_area()
    {
        return (this->x1 - this->x0) * (this->y1 - this->y0);
    }
    inline ll get_perimeter()
    {
        return 2ll * (this->x1 - this->x0 + this->y1 - this->y0);   
    }
};


int main()
{
    static const int NR_RECTANGLES = 3;
    vector<Rectangle> rectangles(NR_RECTANGLES);
    for (auto &rect : rectangles)
    {
        cin >> rect;
    }
    
    auto pinex = [&](auto &self, const int idx) -> pll
    {
        static int nr_taken{};
        static Rectangle cur_rectangle;
        if (idx == NR_RECTANGLES)
        {
            if (nr_taken == 0)
            {
                return {0, 0};
            }
            if (nr_taken & 1)
            {
                return {cur_rectangle.get_area(), cur_rectangle.get_perimeter()};
            }
            return {-cur_rectangle.get_area(), -cur_rectangle.get_perimeter()};
        }

        // Take.
        const auto tmp = cur_rectangle;
        if (nr_taken == 0)
        {
            cur_rectangle = rectangles[idx];
        }
        else
        {
            cur_rectangle.set_intersection(rectangles[idx]);
        }
        ++nr_taken;
        const auto res1 = self(self, idx + 1);
        --nr_taken;
        cur_rectangle = tmp;

        // Don't take.
        const auto res2 = self(self, idx + 1);
        return {res1.first + res2.first, res1.second + res2.second};
    };

    const auto res = pinex(pinex, 0);
    cout << res.first << " " << res.second;
}