Cod sursa(job #534566)

Utilizator vladiiIonescu Vlad vladii Data 15 februarie 2011 20:52:23
Problema Popandai Scor 64
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 310
#define inf 1000000010
#define PII pair<int, int>
#define x first
#define y second

int N, K;
int sol = inf;
int down[maxn], up[maxn];
int sub[maxn][maxn];
PII P[maxn];

int cmp(PII a, PII b) {
    if(a.x != b.x) return a.x < b.x;
    return a.y < b.y;
}

int abs(int val) {
    if(val < 0) return -val;
    return val;
}

int arie(PII p1, PII p2, PII p3) {
    int a = p1.x * p2.y + p3.x * p1.y + p2.x * p3.y;
    int b = p3.x * p2.y + p1.x * p3.y + p2.x * p1.y;
    int rez = abs(a - b);

    return rez;
}

double under(PII ptest, PII p1, PII p2) {
    double A = (double)(p1.y - p2.y) / (p1.x - p2.x);
    double C = (p1.y - A * p1.x);

    return (double)A * ptest.x - ptest.y + C;
}

void calc_sub() {
    int i, j, p;
    for(i=1; i<=N; i++) {
         for(j=i+1; j<=N; j++) {
              for(p=i+1; p<=j-1; p++) {
                   if(under(P[p], P[i], P[j]) > 0) {
                        sub[i][j] ++; sub[j][i] ++;
                   }
              }
         }
    }
}

int calc_points(int a, int b, int c) {
    if(P[a].x > P[b].x) swap(a, b);
    if(P[b].x > P[c].x) swap(b, c);
    if(P[a].x > P[b].x) swap(a, b);

    if(under(P[b], P[a], P[c]) > 0) {
         return sub[a][c] - sub[a][b] - sub[b][c] - 1;
    }
    else {
         return sub[a][b] + sub[b][c] - sub[a][c];
    }
}

void solve() {
    int i, j, p;

    for(i=1; i<=N; i++) {
         for(j=i+1; j<=N; j++) {
              //folosesc diagonala (i, j)
              for(p=0; p<=N; p++) {
                   up[p] = down[p] = inf;
              }
              for(p=1; p<=N; p++) {
                   if(p != i && p != j) {
                        int nrpoints = calc_points(p, i, j);

                        if(under(P[p], P[i], P[j]) > 0) {
                             down[nrpoints] = min(down[nrpoints], arie(P[p], P[i], P[j]));
                        }
                        else {
                             up[nrpoints] = min(up[nrpoints], arie(P[p], P[i], P[j]));
                        }
                   }
              }
              for(p=N-1; p>=0; p--) {
                   down[p] = min(down[p], down[p+1]);
              }
              for(p=0; p<=N; p++) {
                   int val = max(0, K - p);
                   if(up[p] != inf && down[val] != inf) {
                        sol = min(sol, up[p] + down[val]);
                   }
              }
         }
    }
}

int main() {
    FILE *f1=fopen("popandai.in", "r"), *f2=fopen("popandai.out", "w");

    fscanf(f1, "%d %d\n", &N, &K);
    for(int i=1; i<=N; i++) {
         fscanf(f1, "%d %d\n", &P[i].x, &P[i].y);
    }

    sort(P+1, P+N+1, cmp);

    calc_sub();

    solve();

    fprintf(f2, "%.1lf\n", (double)(sol / 2));
    fclose(f1); fclose(f2);
    return 0;
}