Cod sursa(job #1116684)

Utilizator Theorytheo .c Theory Data 22 februarie 2014 19:05:36
Problema Infasuratoare convexa Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <cstdlib>
#include <cstdio>

using namespace std;
ifstream fin ("mosia.in");
ofstream fout ("mosia.out");

const int NMAX = 1206;
const double eps = 0.00001;
const double INF = 10002;

int N; int cnt; int in; double gx, gy;


struct Point {

    double x; double y; double d;

} V[NMAX]; Point last; Point K; Point S[NMAX];

double Arie[NMAX]; bool take[NMAX];

double dist(const Point& A, const Point& B) {

    return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}



bool cmp(const Point& A, const Point& B) {

    return atan2 (A.y - K.y,A.x - K.x) < atan2(B.y - K.y, B.x - K.x);

    //return compare(V[1], A, B);
}

double sarrus(Point A, Point B, Point C) {

    double a = A.y - B.y;
    double b = B.x - A.x;
    double c = B.y * A.x - A.y * B.x;

    return C.x * a + C.y * b + c;
}

bool find_interior(double xn,double yn) {

    S[cnt + 1] = S[1]; S[cnt + 2] = S[2]; Point other; int intersect = 0;
    Point sup;

    sup.x = xn;

    sup.y = yn;

    other.x = sup.x;
    other.y = INF;

    for(int i = 1; i <= cnt; ++i)
        if(sarrus(S[i], S[i + 1], sup) * sarrus(S[i], S[i + 1], other) < 0 &&
           sarrus(sup, other, S[i]) * sarrus(sup, other, S[i + 1]) < 0)
            intersect++;

    if(intersect % 2 == 1) {
        K = sup;
        return true;
    }
    K = sup;
    return false;
}

bool cmp2(Point A, Point B){
    return sarrus(V[1], A, B) < 0;
}

void sort_point() {

    sort(V + 2, V +  N + 1, cmp2);

    S[++cnt] = V[1]; S[++cnt] = V[2];

    for(int i = 3; i <= N; ++i) {

        while(cnt >= 2 && sarrus(S[cnt - 1], S[cnt], V[i]) >= 0) cnt--;

        S[++cnt] = V[i];
    }

}


void read() {

    fin >> N; int ind = 1;
    srand(time(NULL));

    for(int i = 1; i <= N; ++i) {

        fin >> V[i].x >> V[i].y >> V[i].d;
        if(V[i].x < V[ind].x || (fabs(V[i].x - V[ind].x) <= eps && V[i].y < V[ind].y))
            ind = i;
        gx += V[i].x; gy += V[i].y;

    }
    gx /= N; gy /= N;
    swap(V[1], V[ind]);
    sort_point();

    for(double i = -20; i <= 20; ++i)
        for(double j = -20; j <= 20; ++j)

           if(find_interior(gx + i, gy + j))
                return ;


}

void solve() {

    sort(V + 1, V + N + 1, cmp);

    V[N + 1] = V[1]; V[N + 2] = V[2]; V[N + 3] = V[3];
    take[2] = true;

    Arie[0]= Arie[1] = 0;
    for(int i = 2; i <= N + 1; ++i) {

        if(i == N + 1) {
            Arie[i] = Arie[i - 1];
            if(take[i - 2] == false)
                Arie[i] = max(Arie[i], Arie[i - 2] + sqrt(dist(V[i - 1], V[i + 1])) * 0.5 * V[i].d);
            break;

        }
        Arie[i] = max(Arie[i - 1], Arie[i - 2] + sqrt(dist(V[i - 1], V[i + 1])) * 0.5 * V[i].d);
        if(i == 2) continue;

        if(Arie[i - 1] > Arie[i - 2] + sqrt(dist(V[i - 1], V[i + 1])) * 0.5 * V[i].d)
            take[i] = take[i - 1];
        else take[i] = take[i - 2];
    }


    fout << fixed;
    fout <<setprecision(4)<< Arie[N + 1];

}

int main() {

    read();

    solve();

    return 0;
}