Cod sursa(job #166995)

Utilizator raula_sanChis Raoul raula_san Data 28 martie 2008 20:29:31
Problema Popandai Scor 12
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <cstring>
#include <cstdio>
#include <cmath>

#define maxN 301

int N, K;
int X[maxN], Y[maxN], Nr[maxN][maxN];

double R;
double U[maxN], D[maxN];

double Dist(int x0, int y0, int x1, int y1)
{
    return
        sqrt((x0-x1) * (x0-x1) + (y0-y1) * (y0-y1));
}

double Area(int x0, int y0, int x1, int y1, int x2, int y2)
{
    double a, b, c, p;

    a = Dist(x0, y0, x1, y1);
    b = Dist(x1, y1, x2, y2);
    c = Dist(x0, y0, x2, y2);

    p = (a + b + c) * 0.5;

    return
        sqrt(p * (p-a) * (p-b) * (p-c));
}

inline void Swap(int &i, int &j)
{
    int t = i;
    i = j;
    j = t;
}

int Ok(int x1, int x2, int x3)
{
    if(x1 > x2)
        Swap(x1, x2);

    return
        (x3 >= x1 && x3 <= x2);
}

int Prod(int x0, int y0, int x1, int y1, int x2, int y2)
{
    return
        (x2-x0) * (y1-y0) - (x1-x0) * (y2-y0);
}

void ReadData()
{
    freopen("popandai.in", "rt", stdin);

    int i;
    for(scanf("%d %d", &N, &K), i=1; i<=N; ++i)
        scanf("%d %d", X+i, Y+i);

    fclose(stdin);
}

void PreCompute()
{
    int i, j, k;
    for(i=1; i<N; ++i)
        for(j=i+1; j<=N; ++j)
            for(k=1; k<=N; ++k)
             if(k != i && k != j && Ok(X[i], X[j], X[k]))
             {
                int x0 = X[i], y0 = Y[i], x1 = X[j], y1 = Y[j], x2 = X[k], y2 = Y[k];

                if(x0 > x1)
                {
                    Swap(x0, x1);
                    Swap(y0, y1);
                }

                if(Prod(x0, y0, x1, y1, x2, y2) > 0)
                {
                    ++ Nr[i][j];
                    ++ Nr[j][i];
                }
             }
}

void Dynamics()
{
    int i, j, k;

    R = 0x3f3f3f3f;

    for(i=0; i<=N; ++i)
        D[i] = U[i] = 0x3f3f3f3f;

    for(i=1; i<N; ++i)
        for(j=i+1; j<=N; ++j)
        {
            for(k=0; k<=N; ++k)
                D[k] = U[k] = 0x3f3f3f3f;

            for(k=1; k<=N; ++k) if(k != i && k != j)
            {
                int x0 = X[i], y0 = Y[i], x1 = X[j], y1 = Y[j], x2 = X[k], y2 = Y[k];

                int a = i, b = j, c = k;

                if(x0 > x1)
                {
                    Swap(x0, x1);
                    Swap(y0, y1);
                    Swap(a, b);
                }
                if(x0 > x2)
                {
                    Swap(x0, x2);
                    Swap(y0, y2);
                    Swap(a, c);
                }
                if(x1 > x2)
                {
                    Swap(x1, x2);
                    Swap(y1, y2);
                    Swap(b, c);
                }

                int s = Prod(x0, y0, x2, y2, x1, y1);

                if(s > 0)
                {
                    int x = Nr[a][c] - Nr[a][b] - Nr[b][c] - 1;

                    double a = Area(x0, y0, x1, y1, x2, y2);

                    if(D[x] > a) D[x] = a;

                }
                else
                {
                    int x = Nr[a][b] + Nr[b][c] - Nr[a][c];

                    double a = Area(x0, y0, x1, y1, x2, y2);

                    if(U[x] > a) U[x] = a;
                }
            }

            for(k=N-1; k>=0; --k)
            {
                if(D[k+1] < D[k]) D[k] = D[k+1];
                if(U[k+1] < U[k]) U[k] = U[k+1];
            }

            for(k=0; k<=K; ++k)
            {
                if(D[k] + U[K-k] < R) R = D[k] + U[K-k];
                if(U[k] + D[K-k] < R) R = U[k] + D[K-k];
            }
        }
}

void Write()
{
    freopen("popandai.out", "wt", stdout);

    printf("%.1lf", R);

    fclose(stdout);
}

int main()
{
    ReadData();
    PreCompute();
    Dynamics();
    Write();

    return 0;
}