Cod sursa(job #1714485)

Utilizator akaprosAna Kapros akapros Data 8 iunie 2016 14:42:04
Problema Popandai Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.96 kb
#include <bits/stdc++.h>
#define maxN 302
#define zeros(x) x & (-x)
#define inf 2000000000.00
using namespace std;
using namespace std;
int n, k, m, d[maxN][maxN];
double ans[maxN], Ans[maxN], sol;
int Norm[maxN], aib[maxN];
struct coord
{
    int x, y, z;
} v[maxN], cp[maxN], V[maxN];;
int cmp(const coord a, const coord b)
{
    return a.x < b.x;
}
int Cmp(const coord a, const coord b)
{
    return 1LL * (a.y - cp[k].y) * (b.x - cp[k].x) < 1LL * (a.x - cp[k].x) * (b.y - cp[k].y);
}
void add(int x, int y)
{
    int i;
    for (i = x; i <= n; i += zeros(i))
        aib[i] += y;
}
int sum(int x)
{
    int i, s = 0;
    for (i = x; i >= 1; i -= zeros(i))
        s += aib[i];
    return s;
}
double len(int i, int j)
{
    return (double)(sqrt((v[i].y - v[j].y) * (v[i].y - v[j].y) + (v[i].x - v[j].x) * (v[i].x - v[j].x)));
}
double Dist(int i, int j, int k)
{
    int a = v[i].y - v[j].y,
        b = v[j].x - v[i].x,
        c = v[i].x * v[j].y - v[j].x * v[i].y;
    double D = (fabs((a * v[k].x + b * v[k].y + c))) / sqrt(a * a + b * b);

    return D;
}
bool f(int x, int y, int z)
{
    long long a = v[x].y - v[y].y,
              b = v[y].x - v[x].x,
              c = 1LL * v[x].x * v[y].y - 1LL * v[y].x * v[x].y;
    return (1LL * a * v[z].x + 1LL * b * v[z].y + 1LL * c) > 0LL;
}
void read()
{
    int i;
    freopen("popandai.in", "r", stdin);
    scanf("%d %d", &n, &k);
    for (i = 1; i <= n; ++ i)
    {
        scanf("%d %d", &v[i].x, &v[i].y);
        v[i].z = i;
        cp[i] = v[i];
    }
}
void prec()
{
    int i, j;
    m = 0;
    sort(cp + 1, cp + n + 1, cmp);
    for (i = 1; i <= n; ++ i)
        Norm[cp[i].z] = i;

    memcpy(V, cp, sizeof(cp));
    for (i = 1; i < n; ++ i)
    {
        m = i;
        int p = i + 1;
        memset(aib, 0, sizeof(aib));
        sort(cp + i + 1, cp + n + 1, Cmp);

        for (j = i + 1; j <= n; ++ j)
        {
            if (Cmp(cp[p], cp[j]))
                while (p < j)
                {
                    add(Norm[cp[p].z], 1);
                    ++ p;
                }
            d[cp[i].z][cp[j].z] = sum(Norm[cp[j].z] - 1) - sum(Norm[cp[i].z]);
            d[cp[j].z][cp[i].z] = d[cp[i].z][cp[j].z];
        }
        memcpy(cp, V, sizeof(V));
    }
}
void solve()
{
    int i, j, p;
    prec();
    sol = inf;
    for (i = 1; i < n; ++ i)
        for (j = i + 1; j <= n; ++ j)
        {
            for (p = 0; p <= n + 1; ++ p)
                ans[p] = Ans[p] = inf;
            double D, diag = inf;
            for (p = 1; p <= n; ++ p)
                if (i != p && j != p)
                {
                    D = Dist(i, j, p);
                    int x = i, y = j, z = p;
                    if (v[x].x > v[y].x)
                        swap(x, y);

                    if (v[x].x > v[z].x)
                        swap(x, z);

                    if (v[y].x > v[z].x)
                        swap(y, z);
                    int np;
                    if (f(x, z, y))
                    {
                        np = d[x][y] + d[y][z] - d[x][z];
                        if (ans[np] > D)
                            ans[np] = D;
                    }
                    else
                    {
                        np = d[x][z] - d[x][y] - d[y][z] - 1;
                        if (Ans[np] > D)
                            Ans[np] = D;
                    }

                }
            for (p = n - 1; p >= 0; -- p)
            {
                ans[p] = min(ans[p], ans[p + 1]);
                if (p <= k && ans[p] + Ans[k - p] < diag)
                    diag = ans[p] + Ans[k - p];
            }
            double l = len(i, j);
            if (diag * l < sol)
                sol = diag * l;
        }
}
void write()
{
    freopen("popandai.out", "w", stdout);
    sol = sol * 0.5;
    printf("%.5lf", sol);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}