Cod sursa(job #1809519)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 18 noiembrie 2016 23:54:24
Problema Popandai Scor 4
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <bits/stdc++.h>

using namespace std;

const int Nmax = 303;
const int inf = 2e9;
const int max_coord = 30001;
const double PI = 3.14159265359;

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[max_coord+3];
    inline int ub(int x) { return (x&(-x)); }
public:
    void update(int x) { for(; x<=max_coord; 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-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y);
    return ar;
}

bool cmp(int j, int k)
{
    double panta1, panta2;
    panta1 = atan2(p[j].y - p[i].y, p[j].x - p[i].x);
    if(panta1<0) panta1 += 2*PI;

    panta2 = atan2(p[k].y - p[i].y, p[k].x - p[i].x);
    if(panta2<0) panta2 += 2*PI;

    return panta1 < panta2;
}

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

    int i,j;
    vector<int> a;

    for(i=1; i<=n; ++i)
    {
        a.clear();
        aib.clear();
        for(j=i+1; j<=n; ++j) a.push_back(j);
        sort(a.begin(), a.end(), cmp);
        for(auto j : a)
        {
            under[i][j] = under[j][i] = aib.query(p[j].x+1);
            aib.update(p[j].x+1);
        }
    }
}

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)
            if(down[l]!=inf && up[k-l]!=inf)
                ans = min(ans, down[l]+up[k-l]);
    }

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

    return 0;
}