Cod sursa(job #586510)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 2 mai 2011 10:19:28
Problema Popandai Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.25 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define Nmax 303
#define inf 0x3f3f3f
#define INF 2000000000
#define Cmax 30002
#define LL long long
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 sub[Nmax][Nmax];
int over[Nmax],under[Nmax];
int N,K;

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

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, int& arie){
    arie = Arie(P[i],P[j],P[k]);
    puncte=0;

    if( e_sub(i,k,j) ) swap(j,k); else
    if( e_sub(k,j,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(k,j,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; int 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);
    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=a;
                Dr[i][j].b=b;
                Dr[i][j].c=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]++;
    }

    int 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=K-1;k>=0;--k){
                over[k] = Minim(over[k],over[k+1]);
                under[k] = Minim(under[k],under[k+1]);
            }

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

    printf("%d",sol/2);
    printf(".%d\n",(sol%2)*5);
    fclose(stdin); fclose(stdout);
    return 0;
}