Cod sursa(job #443109)

Utilizator space.foldingAdrian Soucup space.folding Data 16 aprilie 2010 01:37:52
Problema Infasuratoare convexa Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <iostream>
#define max(x0, x1, base) (x0.x-base.x!=0)?((x0.y-base.y)/(x0.x-base.x)>(x1.y-base.y)/(x1.x-base.x)?0:1):((x0.y-base.y)>(x1.y-base.y)?0:1)
#define cross_product(A, B, C) (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x)
using namespace std;
struct point
{
    double x, y;
};
point points[120001], stack[120001];
void fix_heap(point basis, point point_array[], long root, point key, long bound)
{
    long vacant = root;
    while (2*vacant <= bound)
    {
        long larger_child=2*vacant;

        if (larger_child < bound && max(point_array[larger_child], point_array[larger_child+1], basis))
                larger_child++;
        if (max(point_array[larger_child], key, basis))
                break;
        else
            point_array[vacant]=point_array[larger_child];
        vacant = larger_child;
    }
    point_array[vacant] = key;
}


void angle_sort(point basis, long n, point point_array[])
{
    point max;
    for(long i=n/2; i>0; --i)
        fix_heap(basis, point_array, i, point_array[i], n);

    for(long i=n; i>1; --i)
    {
        max = point_array[1];
        fix_heap(basis, point_array, 1, point_array[i], i-1);
        point_array[i]=max;
    }
    point_array[0]=point_array[n];
}

void read (long &n, point v[])
{
    freopen("infasuratoare.in", "r", stdin);
    scanf("%ld", &n);
    for (int i=1; i<=n; ++i)
    {
        scanf("%lf%lf", &v[i].x, &v[i].y);
        if(v[i].x<v[0].x || (v[i].x==v[0].x && v[i].y<v[0].y))
            v[0]=v[i];
    }
}


void write (long n, point v[])
{
    freopen("infasuratoare.out", "w", stdout);
    printf("%ld\n", n);
    for (int i=0; i<n; ++i)
        printf("%lf %lf\n", (v+i)->x, (v+i)->y);
}

long convex_hull(long n, point points[], point hull[])
{
    int stack_index=0;
    hull[stack_index++]=points[0];
    hull[stack_index++]=points[1];
    for(long i=2; i<n; )
    {
        hull[stack_index++]=points[i++];
        while(cross_product(hull[stack_index-3], hull[stack_index-2], hull[stack_index-1])<0)
        {
            hull[stack_index-2]=hull[stack_index-1];
            stack_index--;
        }
    }
    return stack_index;
}
int main()
{
    long n, hn;
    read(n, points);
    angle_sort(points[0], n, points);
    hn=convex_hull(n, points, stack);
    write(n, points);
    write(hn, stack);
    return 0;
}