Cod sursa(job #2203963)

Utilizator EclipseTepes Alexandru Eclipse Data 13 mai 2018 21:26:46
Problema Infasuratoare convexa Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define dMAX 120000
#define PI 3.14159265359

using namespace std;

int n;

struct Point{
    int idx;
    double x, y;
} arr[dMAX + 2];

double angles[dMAX + 2];
double z = 2;

int h, lowestY;
Point myStack[dMAX + 2];
Point pVerif, newP;

ifstream fin("infasuratoare.in");
ofstream fout("infasuratoare.out");

double Angle(Point p, Point q) {
    double dx, dy;
    dy = q.y - p.y;
    dx = q.x - p.x;
    if (atan2(dy, dx) < 0) return z * PI + atan2(dy, dx);
    return atan2(dy, dx);
}

bool CompareY(Point p, Point q) {
    if (p.y == q.y) return p.x < q.y;
    return p.y < q.y;
}

bool CompareA(Point p, Point q) {
    //return angles[p.idx] < angles[q.idx];
    //return Angle(arr[p.idx], arr[1]) < Angle(arr[q.idx], arr[1]);
    return Angle(p, arr[1]) < Angle(q, arr[1]);
}

bool Colinear(Point p, Point q, Point r) {
    return (p.y - q.y) * (r.x - q.x) - (p.x - q.x) * (r.y - q.y) == 0;
}

bool CounterClockwiseTurn(Point p, Point q, Point r) {
    if (Colinear(p, q, r)) return true;
    return (p.x * q.y + q.x * r.y + r.x * p.y
          - p.x * r.y - q.x * p.y - r.x * q.y > 0);
}

int main()
{
    int i, j;
    fin >> n;
    lowestY = 1;
    for (i = 1; i <= n; i++) {
        fin >> arr[i].x >> arr[i].y;
        if (arr[i].y < arr[lowestY].y) {
            lowestY = i;
        } else if (arr[i].y == arr[lowestY].y) {
            if (arr[i].x < arr[lowestY].x) lowestY = i;
        }
        arr[i].idx = i;
    }
    //swap(arr[1], arr[lowestY]);
    sort(arr + 1, arr + 1 + n, CompareY);
    sort(arr + 1, arr + 1 + n, CompareA);

    myStack[++h] = arr[1];
    myStack[++h] = arr[2];
    for (i = 3; i <= n; i++) {
        pVerif = arr[i];
        while (!CounterClockwiseTurn(myStack[h - 1], myStack[h], pVerif) && h >= 2)
            h--;
        myStack[++h] = pVerif;
    }
    fout << h << '\n';
    for (i = 1; i <= h; i++) fout << setprecision(6) << fixed <<  myStack[i].x << ' ' << myStack[i].y << '\n';
    return 0;
}