#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <sstream>
#include <iomanip>
#include <cmath>
using std::string;
using std::shared_ptr;
using std::istringstream;
using std::make_shared;
class Figure {
public:
virtual string Name() const = 0;
virtual double Perimeter() const = 0;
virtual double Area() const = 0;
};
class Triangle : public Figure {
public:
Triangle(const int& a, const int& b, const int& c)
: a_(a), b_(b), c_(c) {}
string Name() const {
return "TRIANGLE";
}
double Perimeter() const {
return a_ + b_ + c_;
}
double Area() const {
double semi_perimeter = Perimeter() / 2;
return sqrt(semi_perimeter * (semi_perimeter - a_) *
(semi_perimeter - b_) * (semi_perimeter - c_));
}
private:
const int a_, b_, c_;
};
class Rect : public Figure {
public:
Rect(const int& width, const int& height)
: width_(width), height_(height) {}
string Name() const {
return "RECT";
}
double Perimeter() const {
return (width_ + height_) * 2;
}
double Area() const {
return width_ * height_;
}
private:
const int width_, height_;
};
class Circle : public Figure {
public:
explicit Circle(const int& radius)
: radius_(radius) {}
string Name() const {
return "CIRCLE";
}
double Perimeter() const {
return 2 * PI * radius_;
}
double Area() const {
return PI * radius_ * radius_;
}
private:
const int radius_;
const double PI = 3.14;
};
shared_ptr<Figure> CreateFigure(istringstream& is) {
string figure_type;
is >> figure_type;
if (figure_type == "RECT") {
int width, height;
is >> width >> height;
return make_shared<Rect>(width, height);
} else if (figure_type == "TRIANGLE") {
int a, b, c;
is >> a >> b >> c;
return make_shared<Triangle>(a, b, c);
} else {
int radius;
is >> radius;
return make_shared<Circle>(radius);
}
}