Cod sursa(job #1498968)

Utilizator lflorin29Florin Laiu lflorin29 Data 9 octombrie 2015 22:30:14
Problema Popandai Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

constexpr int kLLimit = 302;

int N, K;
vector <double> MA;
vector < pair <int, int>> Points;
vector < vector <int>> below;

void read() {
    ifstream fin("popandai.in");

    fin >> N >> K;
    Points.resize(N);

    for (int i = 0; i < N; ++i)
        fin >> Points[i].first >> Points[i].second;
}

int unh (const pair <int, int>& X, const pair<int, int>& Y, const pair <int, int>& Z) {
    return X.first * (Y.second - Z.second) - X.second * (Y.first - Z.first) + Y.first * Z.second - Y.second * Z.first;
}

void getUnder() {
    sort(begin(Points), end(Points));

    below.resize(N, vector<int>(N));
    for (int i = 0; i < N - 1; ++i)
        for (int j = i + 1; j < N; ++j)
           for (int k = i + 1; k < j; ++k)
               below[i][j] += unh(Points[i], Points[j], Points[k]) < 0;
}

inline int Resp (int X, int Y, int Z) {
    if (X > Y)
       swap(X, Y);
    if (X > Z)
       swap(X, Z);
    if (Y > Z)
       swap(Y, Z);

    if (unh(Points[X], Points[Z], Points[Y]) < 0)
        return below[X][Z] - below[X][Y] - below[Y][Z] - 1;
     return below[X][Y] + below[Y][Z] - below[X][Z];
}

void solve() {
    double ans = 1e12;
    for (int i = 0; i < N; ++i)
       for (int j = i + 1; j < N; ++j) {
           MA = vector<double>(N + 3, 1e12);

           for (int k = 0; k < N; ++k) {
              if (k == i or k == j or unh(Points[i], Points[j], Points[k]) >= 0) // under segment
                continue;
              const int inside = Resp(i, j, k);

              MA[inside] = min(MA[inside], 0.5 * abs(unh(Points[i], Points[j], Points[k])));
           }

           for (int k = N ; k >= 0; k--)
              MA[k] = min(MA[k], MA[k + 1]);

           for (int k = 0; k < N; ++k) {
               if (k == i or k == j or unh(Points[i], Points[j], Points[k]) < 0)
                 continue;

               const int inside = max(0, K - Resp(i, j, k));
               ans = min(ans, MA[inside] + 0.5 * unh(Points[i], Points[j], Points[k]));
           }
       }
    ofstream ("popandai.out") << fixed << setprecision(1) << ans;
}

int main() {
    read();
    getUnder();
    solve();
    return 0;
}