/* O(N^3) algorithm */
#include <fstream>
#include <cmath>
#include <vector>
#include <utility>
#include <algorithm>
#include <iomanip>
#include <set>
using namespace std;
double getDet3(pair<double, double> p1, pair<double, double> p2, pair<double, double> p3)
{
return p1.first * (p2.second - p3.second) +
p2.first * (p3.second - p1.second) +
p3.first * (p1.second - p2.second);
}
bool isExtremePoint(int pointIndex, pair<double, double> points[], int N)
{
int i, j, k;
double triangleArea, area1, area2, area3;
for (i = 0; i < N - 2; i++)
if (i != pointIndex)
for (j = i + 1; j < N - 1; j++)
if (j != pointIndex)
for (k = j + 1; k < N; k++)
if (k != pointIndex)
{
triangleArea = abs(getDet3(points[i], points[j], points[k]));
area1 = abs(getDet3(points[pointIndex], points[i], points[j]));
area2 = abs(getDet3(points[pointIndex], points[i], points[k]));
area3 = abs(getDet3(points[pointIndex], points[k], points[j]));
if (triangleArea == area1 + area2 + area3)
return false;
}
return true;
}
pair<double, double> center(numeric_limits<double>::max(), numeric_limits<double>::max());
struct cmp
{
bool operator() (const pair<double, double> &a, const pair<double, double> &b) {
return atan2(a.second - center.second, a.first - center.first) < atan2(b.second - center.second, b.first - center.first);
}
};
int main()
{
int N, i, j, k;
ifstream f("infasuratoare.in");
f >> N;
pair<double, double> points[N];
for (i = 0; i < N; i++)
{
f >> points[i].first >> points[i].second;
if (points[i].second < center.second)
center = points[i];
else if (points[i].second == center.second && points[i].first < center.first)
center = points[i];
}
f.close();
sort(points, points + N, [] (const pair<double, double> &a, const pair<double, double> &b) {
return atan2(a.second - center.second, a.first - center.first) < atan2(b.second - center.second, b.first - center.first);
});
bool extremeEdge;
set<pair<double, double>, cmp> sol;
for (i = 0; i < N - 1; i++)
for (j = i + 1; j < N; j++)
{
extremeEdge = true;
for (k = 0; k < N; k++)
if (k != i && k != j && getDet3(points[i], points[j], points[k]) <= 0)
extremeEdge = false;
if (extremeEdge)
sol.insert(points[i]), sol.insert(points[j]);
}
ofstream g("infasuratoare.out");
g << sol.size() << '\n';
for (auto it = sol.begin(); it != sol.end(); it++)
g << fixed << setprecision(12) << it->first << ' ' << it->second << '\n';
g.close();
return 0;
}