Cod sursa(job #586434)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 1 mai 2011 10:48:14
Problema Popandai Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define Nmax 303
#define inf 0x3f3f3f
#define INF 1000000000.00
#define Cmax 30002
using namespace std;

struct punct{
    int x,y;
    inline bool operator< ( const punct &a )const{
        return x < a.x;
    }
} P[Nmax];
struct dreapta{
    int a,b,c;
} Dr[Nmax][Nmax];

int exsub[Cmax];
int sub[Nmax][Nmax];
double over[Nmax],under[Nmax];
int N,K;

inline double Minim(double x,double y){ return x<y ? x:y; }
double Abs(double x){ return x>0 ? x:-x; }
inline double Arie( punct p1,punct p2,punct p3 ){
    return Abs( (double)p1.x*p2.y+p2.x*p3.y+p3.x*p1.y - p1.y*p2.x-p2.y*p3.x-p3.y*p1.x )/2;
}

int a,b,c;
inline void ABC(int i,int j){
    a=P[i].y-P[j].y;
    b=P[j].x-P[i].x;
    c=P[i].x*P[j].y - P[j].x*P[i].y;
}

inline int e_sub(int i,int j,int k){
    return ( P[k].x >= P[i].x && P[k].x<=P[j].x && Dr[i][j].a*P[k].x+Dr[i][j].b*P[k].y+Dr[i][j].c < 0 );
}
inline int e_deasupra(int i,int j,int k){
    return ( P[k].x >= P[i].x && P[k].x<=P[j].x && Dr[i][j].a*P[k].x+Dr[i][j].b*P[k].y+Dr[i][j].c > 0 );
}

inline void check(int i,int j,int k,int& puncte, double& arie){
    arie = Arie(P[i],P[j],P[k]);
    puncte=0;

    if( e_sub(i,k,j) ) swap(j,k); else
    if( e_sub(j,k,i) ) swap(i,k);
    if( e_sub(i,j,k) ) puncte = sub[i][j]-sub[i][k]-sub[k][j]-1+sub[k][k];

    if( puncte ) return;

    if( e_deasupra(i,k,j) ) swap(j,k); else
    if( e_deasupra(j,k,i) ) swap(i,k);
    if( e_deasupra(i,j,k) ) puncte = -sub[i][j]+sub[i][k]+sub[k][j]-sub[k][k];
}

int main(){
    int i,j,k,puncte=0; punct aux; double arie;
    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), exsub[P[i].x]++;
    sort(P+1,P+N+1);

    for(i=1;i<=N;++i)
        for(j=1;j<=N;++j)
            if( i!=j ){
                ABC(i,j);
                Dr[i][j]={a,b,c};
            }

    for(i=1;i<=N;++i){
        for(j=i+1;j<=N;++j){
            for(k=1;k<=N;++k)

                if( e_sub(i,j,k) )
                    sub[i][j]++;

            sub[j][i]=sub[i][j];
        }

        for(k=1;k<=N;++k)
            if( P[k].x==P[i].x && P[k].y < P[i].y )
                sub[i][i]++;
    }

    double sol=INF;
    for(i=1;i<=N;++i){
        for(j=i+1;j<=N;++j){

            for(k=0;k<=N;++k) over[k]=under[k]=INF;

            for(k=1;k<=N;++k)
                if( Dr[i][j].a*P[k].x+Dr[i][j].b*P[k].y+Dr[i][j].c < 0 ){
                    check(i,j,k,puncte,arie);
                    under[puncte]=Minim(under[puncte],arie);

                }else
                if( Dr[i][j].a*P[k].x+Dr[i][j].b*P[k].y+Dr[i][j].c > 0 ){
                    check(i,j,k,puncte,arie);
                    over[puncte]=Minim(over[puncte],arie);

                }

            for(k=0;k<=K;++k)
                if( over[k]+under[K-k] < sol )
                    sol=over[k]+under[K-k];
        }
    }

    printf("%.1lf\n",sol);
    fclose(stdin); fclose(stdout);
    return 0;
}