Pagini recente » Cod sursa (job #1158099) | Cod sursa (job #506740) | Cod sursa (job #688328) | Monitorul de evaluare | Cod sursa (job #341837)
Cod sursa(job #341837)
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define MAX_N 310
#define inf 2147000000
int n, k;
int prec[MAX_N][MAX_N], A[3];
int sus[MAX_N], smin[MAX_N], jos[MAX_N], jmin[MAX_N];
struct punct {
int x;
int y;
} V[MAX_N];
double sol = inf;
inline int cmp(punct P, punct Q) {
if (P.x != Q.x) return P.x < Q.x;
else return P.y < Q.y;
}
inline int cmp2(int p, int q) {
if (V[p].x != V[q].x) return V[p].x < V[q].x;
else return V[p].y < V[q].y;
}
void cit() {
freopen("popandai.in", "r", stdin);
freopen("popandai.out", "w", stdout);
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%d %d", &V[i].x, &V[i].y);
sort(V + 1, V + n + 1, cmp);
}
double tang(punct P, punct Q) {
if (P.x != Q.x) return 1.0 * (Q.y - P.y) / (Q.x - P.x);
else {
if (Q.y < P.y) return -inf;
else return inf;
}
}
void precalculare() {
for (int i = 1; i <= n - 1; i++)
for (int j = i + 1; j <= n; j++) {
if (V[j].x != V[i].x)
for (int k = i - 1; k < j; k++)
if (k) {
if (k > i && tang(V[i], V[k]) < tang(V[i], V[j]))
prec[i][j]++;
if (k == i - 1 && V[k].x == V[i].x) prec[i][j]++;
}
prec[j][i] = prec[i][j];
}
}
int det (int i, int j, int k) {
return V[i].x * V[j].y + V[j].x * V[k].y + V[k].x * V[i].y -
V[i].y * V[j].x - V[j].y * V[k].x - V[k].y * V[i].x;
}
int sup(int i, int j, int k) {
return abs(V[i].x * V[j].y + V[j].x * V[k].y + V[k].x * V[i].y -
V[i].y * V[j].x - V[j].y * V[k].x - V[k].y * V[i].x);
}
int nr_punct(int i, int j, int k) {
A[0] = i; A[1] = j; A[2] = k;
sort(A, A + 3, cmp2);
i = A[0]; j = A[1]; k = A[2];
int ret = 0;
if (V[i].x != V[j].x && V[j].x != V[k].x) {
int gas = 0;
if (V[j - 1].x == V[j].x) gas = 1;
if (det(i, j, k) < 0) {
ret = prec[i][j] + prec[j][k] - prec[i][k];
if (gas) ret--;
}
else {
ret = prec[i][k] - prec[i][j] - prec[j][k] - 1;
if (gas) ret++;
}
}
else {
if (V[i].x == V[j].x)
ret = prec[j][k] - prec[i][k] - 1;
else
ret = prec[i][k] - prec[i][j] - 1;
}
return ret;
}
void solve() {
precalculare();
for (int i = 1; i < n; i++)
for (int j = i + 1; j <= n; j++) {
sus[0] = jos[0] = 0;
for (int t = 1; t <= n; t++) {
if (t != i && t != j) {
if (det(i, j, t) > 0) sus[++sus[0]] = t;
else jos[++jos[0]] = t;
}
}
for (int t = 0; t <= k; t++)
smin[t] = jmin[t] = inf;
for (int t = 1; t <= sus[0]; t++) {
int arie = sup(i, j, sus[t]), nr = nr_punct(i, j, sus[t]);
if (arie < smin[nr])
smin[nr] = arie;
}
for (int t = 1; t <= jos[0]; t++) {
int arie = sup(i, j, jos[t]), nr = nr_punct(i, j, jos[t]);
if (arie < jmin[nr])
jmin[nr] = arie;
}
for (int t = k; t >= 0; t--)
jmin[t] = min(jmin[t], jmin[t + 1]);
for (int t = 0; t <= k; t++)
if (smin[t] != inf && jmin[k - t] != inf)
sol = min(sol, 1.0 * (smin[t] + jmin[k - t]) / 2);
}
printf("%.1lf\n", 1.0 * sol / 2);
}
int main() {
cit();
solve();
return 0;
}