Cod sursa(job #1026791)

Utilizator romircea2010FMI Trifan Mircea Mihai romircea2010 Data 12 noiembrie 2013 00:00:06
Problema Popandai Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.79 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#define INF 2000000000
#define lim 1000000
#define Next ++position == lim?f.read(buffer, lim), position = 0:0
#define NMax 310
#define KMax 310

using namespace std;

/**de impartit aria la 2 !!*/

int sol = INF;
int stanga[NMax], dreapta[NMax];
int nrunder[NMax][NMax];
int n, K;
ifstream f ("popandai.in");
int position;
char buffer[lim];
struct punct
{
    int x, y;
    punct()
    {
        x = y = 0;
    }
    punct (const int _x, const int _y)
    {
        x = _x;
        y = _y;
    }
    bool operator < (const punct &other) const
    {
        if (x == other.x)
            return y > other.y;
        return x < other.x;
    }
};
punct a[NMax];

inline void Read(int &x)
{
    for (; buffer[position] < '0' || buffer[position] > '9'; Next);
    for (x = 0; '0' <= buffer[position] && buffer[position] <= '9'; x = x*10 + buffer[position] - '0', Next);
}

void Read()
{
    Read(n), Read(K);
    int x, y, i;
    for (i=1; i<=n; ++i)
    {
        Read(x), Read(y);
        a[i] = punct(x, y);
    }
}

inline int Determinant(const punct A, const punct B, const punct C)
{
    ///return a[i].y * a[k].x + a[j].x * a[k].y + a[i].x * a[j].y - a[i].y * a[j].x - a[j].y * a[k].x - a[i].x * a[k].y;
    return A.y * C.x + B.x * C.y + A.x * B.y - A.y * B.x - B.y * C.x - A.x * C.y;
}

inline int NrPuncte(const int i, const int j, const int k)
{
    /// i < j deci asta inseamna ca a[i].x < a[j].x; daca a[i].x == a[j].x atunci a[i].y > a[j].y
    int st, mij, dr;
    if (k < i)
        st = k, mij = i, dr = j;
    else
    {
        st = i;
        if ( k < j )
            mij = k, dr = j;
        else
            mij = j, dr = k;
    }
    if (Determinant(a[st], a[dr], a[mij]) > 0)
        return nrunder[st][mij] + nrunder[mij][dr] - nrunder[st][dr];
    return nrunder[st][dr] - nrunder[st][mij] - nrunder[mij][dr] - 1;
}


inline int Aria(const punct A, const punct B, const punct C)
{
    return abs(A.y * C.x + B.x * C.y + A.x * B.y - A.y * B.x - B.y * C.x - A.x * C.y);
}

void Precalc()
{
    int i, j, k;
    for (i=1; i<=n; ++i)
        for (j=i+1; j<=n; ++j)
            for (k = 1; k<j; ++k)
                if ((min(a[i].x, a[j].x) <= a[k].x && a[k].x < max(a[i].x, a[j].x)) && (Determinant(a[i], a[j], a[k]) < 0))
                    ++nrunder[i][j];
}

void Solve()
{
    sort(a+1, a+n+1);
    Precalc();
    int i, j, k, det;
    for (i=1; i<=n; ++i)
    {
        for (j=i+1; j<=n; ++j)
        {
            for (k=0; k<=n; ++k)
                stanga[k] = dreapta[k] = INF;
            for (k=1; k<=n; ++k)
            {
                if (k == i || k == j)
                    continue;
                det = Determinant(a[i], a[j], a[k]);
                if (det > 0)
                {
                    /// stanga
                    int nrpoints = NrPuncte(i, j, k);
                    stanga[nrpoints] = min(stanga[nrpoints], Aria(a[i], a[j], a[k]));
                }
                else
                {
                    ///dreapta
                    int nrpoints = NrPuncte(i, j, k);
                    dreapta[nrpoints] = min(dreapta[nrpoints], Aria(a[i], a[j], a[k]));
                }
            }
            for (k=n; k; --k)
                stanga[k-1] = min(stanga[k-1], stanga[k]),
                dreapta[k-1] = min(dreapta[k-1], dreapta[k]);
            for (k = 0; k <= K; ++k)
                if (stanga[k] != INF && dreapta[K-k] != INF)
                    sol = min (sol, stanga[k] + dreapta[K-k]);
        }
    }
}

void Write()
{
    FILE *g = fopen ("popandai.out", "w");
    fprintf(g, "%.1lf\n", 1.0*sol/2);
    fclose(g);
}

int main()
{
    Read();
    Solve();
    Write();
    return 0;
}