


#include <iostream>
#include <math.h>

using namespace std;

class P {
protected:
  float x, y; //!< Coordinates
public:
  P();
  P(float, float);
  friend float D(const P&, const P&);
  friend ostream& operator<<(ostream&, const P&);
  friend P operator+(const P&, const P&);
  friend P operator/(const P&, float);

  float X() const;
};

//! Empty constructor
P::P()
{
  x = 0.0; y = 0.0;
}

//! Constructor
P::P(float a, float b)
{
  x = a; y = b;
}

//! Distance between two points
float D(const P& pa, const P& pb)
{
  P ab(pb.x - pa.x, pb.y - pa.y);
  return sqrt(ab.x * ab.x + ab.y * ab.y);
}

//! Overloaded stream operator
ostream& operator<<(ostream& s, const P& p)
{
  s << '(' << p.x << ',' << p.y << ')';
  return s;
}

//! Overloaded sum
P operator+(const P& pa, const P& pb)
{
  return P(pa.x + pb.x, pa.y + pb.y);
}

//! Overloaded division by real
P operator/(const P& pa, float b)
{
  return P(pa.x / b, pa.y / b);
}

//! Return the X coordinate
float P::X() const
{
  return x;
}

class C
{
protected:
  P c;  //!< Centre
  float r; //!< Rayon.
public:
  C();
  C(const P&, float);
  friend ostream& operator<<(ostream&, const C&);
};

//! Empty constructor
C::C()
{
  // c = P(0.0, 0.0);
  r = 0.0;
}

//! Constructor
C::C(const P& p, float a)
{
  c = p; r = a;
}

//! Overloaded stream operator
ostream& operator<<(ostream& s, const C& cercle)
{
  s << "Cercle(c=" << cercle.c << ",r=" << cercle.r << ')';
  return s;
}

#include <vector>

class E {
protected:
  vector<P> t; //!< Tableau de points.
public:
  E();
  void Aj(const P&);
  void Sup(int);
  P Bary() const;
  C Env() const;
  E Gauche() const;
};


//! Empty constructor
E::E()
{

}

//! Add an element to the set
void E::Aj(const P& p)
{
  t.push_back(p);
}

//! Remove an element to the set
void E::Sup(int e)
{
  if (e >= t.size())
  {
    return;
  }
  t.erase(t.begin() + e);
}

//! Barycenter
P E::Bary() const
{
  P b;  // Grace à P::P() qui init bien à (0,0) sinon P b=P(0,0);

  for (int i = 0; i < t.size(); i++)
  {
    b = b + t[i]; // Grace a + de P
  }
  b = b / t.size(); // Grace à / de P
  return b;
}

//! Bouding circle
C E::Env() const
{
  float r = 0.0;

  P g = Bary();

  // Calcul
  for (int i = 0; i < t.size(); i++)
  {
    float ri = D(t.at(i), g);
    if (ri > r)
    {
      r = ri;
    }
  }
  return C(g, r);
}

//! Left subset
E E::Gauche() const
{
  E l;

  P g = Bary();

  // Calcul
  for (int i = 0; i < t.size(); i++)
  {
    if (t.at(i).X() < g.X())
    {
      l.Aj(t.at(i));
    }
  }

  return l;
}
