Cod sursă (job #307253)

Utilizator avatar AndreiStan Andrei Stan AndreiStan IP ascuns
Problemă Înfășurătoare convexă Compilator cpp | 1,56 kb
Rundă Arhiva de probleme Status evaluat
Dată 14 iun. 2017 11:17:53 Scor 100
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;
ifstream f("infasuratoare.in");
ofstream g("infasuratoare.out");
struct punct
{
    int x, y;
};

punct p[100002], st[1002];
int N, H;

void afis()
{
    g << H << '\n';
    for(int i = 1; i <= H; i++)
        g << st[i].x << ' ' << st[i].y << '\n';
}

void swap(punct &A, punct &B)
{
    punct aux;
    aux = A;
    A = B;
    B = aux;
}

inline long long patrat(long long x)
{
    return x * x;
}

long long distp(const punct &A, const punct &B)
{
    return patrat(A.x - B.x) + patrat(A.y - B.y);
}

int compy(const punct &A, const punct &B)
{
    if(A.y == B.y) return A.x < B.x;
    return A.y < B.y;
}

long long det(const punct &A, const punct &B, const punct &C)
{
    return (long long)(A.x - B.x) * (B.y - C.y) - (long long)(A.y - B.y) * (B.x - C.x);
}

int compd(const punct &A, const punct &B)
{
    long long dd = det(p[1], A, B);
    if(dd == 0)
        return distp(p[1], A) < distp(p[1], B);
    return dd > 0;
}

int main()
{
    f >> N;
    int ip0 = 1;
    for(int i = 1; i <= N; i++)
    {
        f >> p[i].x >> p[i].y;
        if(compy(p[i], p[ip0]))
            ip0 = i;
    }
    swap(p[ip0], p[1]);
    sort(p + 2, p + N + 1, compd);
    st[1] = p[1];
    st[2] = p[2];
    H = 2;
    p[N + 1] = p[1];
    for(int i = 3; i <= N + 1; i++)
    {
        while(H >= 2 && det(st[H - 1], st[H], p[i]) <= 0)
            H--;
        st[++H] = p[i];
    }
    H--;
    afis();
    return 0;
}