Pagini recente » Cod sursa (job #2263116) | Istoria paginii runda/concurs_freshmen_3 | Cod sursa (job #1231623) | Cod sursa (job #761732) | Cod sursa (job #1659916)
//#include "Processing.h"
#include <vector>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std::placeholders;
using namespace std;
struct Point
{
double x;
double y;
};
struct OrderAsc
{
bool operator() (const Point& A, const Point& B)
{
return A.x < B.x || (A.x == B.x && A.y < B.y);
}
};
class Processing
{
public:
void LoadData(const char* filePath)
{
ifstream f(filePath);
int n;
f >> n;
for (int i = 1; i <= n; ++i)
{
Point p;
f >> p.x >> p.y;
mPoints.push_back(p);
}
}
void SaveData(const char* filePath)
{
ofstream g(filePath);
g << mHullResult.size() << "\n";
g << setprecision(6) << fixed;
for (auto p : mHullResult)
{
g <<p.x << " " << p.y << " \n";
}
}
bool Process()
{
size_t nrOfPoints = mPoints.size();
size_t hullIndex = 0;
mHullResult.resize(2 * nrOfPoints);
sort(mPoints.begin(), mPoints.end(), OrderAsc());
//DebugOutput("Start => HullIndex: %d", hullIndex);
// Build lower hull
/* Binders */ //std::cref( ) const type&
for_each(mPoints.begin(), mPoints.end(), bind(&Processing::FindOptimalCrossProduct, this, _1, std::ref(hullIndex), 2));
/* Lambda functions */
/*for_each(mPoints.begin(), mPoints.end(), [&](const Point& point)
{
FindOptimalCrossProduct(point, hullIndex, 2);
});*/
/* Classic for loop */
/*
for (auto p : mPoints)
{
FindOptimalCrossProduct(hullIndex, 2, p);
// DebugOutput("HullIndex: %d => (%d,%d)", hullIndex, (int)p.x, (int)p.y);
// mHullResult[hullIndex++] = p;
}
*/
//DebugOutput("Build upper hull => index: %d", hullIndex);
// Build upper hull
const size_t limit = hullIndex + 1;
for (int i = nrOfPoints - 2; i >= 0; i--)
{
auto p = mPoints[i];
FindOptimalCrossProduct(p, hullIndex, limit);
/*
DebugOutput("HullIndex: %d => (%d,%d)", hullIndex, (int)p.x, (int)p.y);
mHullResult[hullIndex++] = p;
*/
}
mHullResult.resize(hullIndex);
return true;
}
protected:
/*
2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
Returns a positive value, if OAB makes a counter-clockwise turn, negative for clockwise turn, and zero if the points are collinear.
*/
static double CrossProduct(const Point& O, const Point& A, const Point& B)
{
return (long)(A.x - O.x) * (B.y - O.y) - (long)(A.y - O.y) * (B.x - O.x);
}
void FindOptimalCrossProduct(const Point& point, size_t& hullIndex, const size_t limit)
{
while (hullIndex >= limit &&
CrossProduct(mHullResult[hullIndex - 2], mHullResult[hullIndex - 1], point) <= 0)
{
hullIndex--;
}
//DebugOutput("HullIndex: %d => (%d,%d)", hullIndex, (int)point.x, (int)point.y);
mHullResult[hullIndex++] = point;
}
private:
vector<Point> mPoints;
vector<Point> mHullResult;
};
int main()
{
auto proc = Processing();
proc.LoadData("infasuratoare.in");
proc.Process();
proc.SaveData("infasuratoare.out");
return 0;
}