Cod sursa(job #1809392)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 18 noiembrie 2016 21:48:25
Problema Popandai Scor 88
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

const int Nmax = 303;
const int inf = 1e9;

struct point
{
    int x, y;
    bool operator < (const point &other) const
    {
        return (x==other.x ? y<other.y : x<other.x);
    }
};

int i, n, k, j, l, ans=inf, cnt, arie;
int down[Nmax], up[Nmax], under[Nmax][Nmax];
point p[Nmax];

struct AIB
{
    int a[Nmax];
    inline int ub(int x) { return (x&(-x)); }
public:
    void update(int x) { for(; x<=n; x+=ub(x)) ++a[x]; }
    int query(int x) { int ans=0; for(; x; x-=ub(x)) ans += a[x]; return ans; }
    void clear() { memset(a, 0, sizeof(a)); }
} aib;


int det(int id1, int id2, int id3)
{
    point a = p[id1], b = p[id2], c = p[id3];
    int ar = a.x*b.y + b.x*c.y + c.x*a.y;
       ar -= a.x*c.y + b.x*a.y + c.x*b.y;
    return ar;
}

void precompute()
{
    sort(p+1, p+n+1);

    int i,j,k;
    for(i=1; i<=n; ++i)
    for(j=i+1; j<=n; ++j)
    {
        for(k=i+1; k<=j-1; ++k)
            under[i][j] += (det(i,j,k)<0);
        under[j][i] = under[i][j];
    }
}

int triangle(int a, int b, int c)
{
    if(a>b) swap(a,b);
    if(a>c) swap(a,c);
    if(b>c) swap(b,c);

    if(det(a,c,b) > 0) return under[a][b] + under[b][c] - under[a][c];
    return under[a][c] - under[a][b] - under[b][c] - 1;
}

int main()
{
    freopen("popandai.in", "r", stdin);
    freopen("popandai.out", "w", stdout);

    scanf("%d %d", &n, &k);

    for(i=1; i<=n; ++i)
        scanf("%d %d", &p[i].x, &p[i].y);

    precompute();

    for(i=1; i<=n; ++i)
    for(j=i+1; j<=n; ++j)
    {
        for(l=0; l<=n; ++l) down[l] = up[l] = inf;

        for(l=1; l<=n; ++l)
        {
            cnt = triangle(i,j,l);
            arie = det(i,j,l);
            if(arie>0) up[cnt] = min(up[cnt], arie);
            else down[cnt] = min(down[cnt], -arie);
        }

        for(l=n-1; l>=0; --l)
        {
            down[l] = min(down[l], down[l+1]);
            up[l] = min(up[l], up[l+1]);
        }

        for(l=0; l<=k; ++l)
            ans = min(ans, down[l]+up[k-l]);
    }

    printf("%.1lf\n", (double)ans/2);

    return 0;
}