Cod sursa(job #82951)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 9 septembrie 2007 15:45:41
Problema Popandai Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <stdio.h>
#include <algorithm>
#include <string>

using namespace std;

#define maxn 310
#define maxx 30010
#define maxv 10000000000LL
#define LSB(x) ((x^(x-1))&x)
#define db double           

int n,m,l;
int X,Y;
short a[maxn],b[maxn];
short s[maxn],p[maxn],q[maxn];
short c[maxx];
short under[maxn][maxn];
db v[maxn],u[maxn],sol;
char down[maxn];

int cmp(int x,int y)
{
    return (b[s[x]]-Y)*(a[s[y]]-X)<(b[s[y]]-Y)*(a[s[x]]-X);
}

int cmp2(int x,int y)
{
    return (a[x]<a[y]) || ((a[x]==a[y]) && (b[x]<b[y]));
}

inline void update(int x)
{
     for (;x<maxx;x+=LSB(x)) c[x]++;
}

inline int query(int x)
{
    int rez=0;
    for (;x>0;x-=LSB(x)) rez+=c[x];
    
    return rez;
}

inline db arie(int x1,int x2,int x3,int y1,int y2,int y3)
{
    return 1.0*x1*y2-x3*y2+x2*y3-x1*y3+x3*y1-x2*y1;
}

inline int nr(int p1,int p2,int p3)
{
    int rez=0;
    l=3;
    p[1]=p1,p[2]=p2,p[3]=p3;
    sort(p+1,p+l+1,cmp2);
    p1=p[1],p2=p[2],p3=p[3];
    
    if (arie(a[p1],a[p3],a[p2],b[p1],b[p3],b[p2])<=0) return under[p1][p3]-under[p1][p2]-under[p2][p3]+down[p2]-1;
    return rez=under[p1][p2]+under[p2][p3]-under[p1][p3]-down[p2];
}

void prep(int pos)
{
     int i;
     X=a[pos],Y=b[pos];
     memset(c,0,sizeof(c));
     
     for (i=1;i<=l;i++) p[i]=i;
     
     sort(p+1,p+l+1,cmp);
     
     for (i=1;i<=l;i++)
     {
         under[pos][s[p[i]]]=query(a[s[p[i]]]+1);
         under[s[p[i]]][pos]=under[pos][s[p[i]]];
         update(a[s[p[i]]]+1);
     }
}

int main()
{
    freopen("popandai.in","r",stdin);
    freopen("popandai.out","w",stdout);
    
    scanf("%d %d ",&n,&m);
    
    int i,j,k,x;
    db aux;
    
    for (i=1;i<=n;i++) 
    {
        scanf("%d %d ",&a[i],&b[i]);
        q[i]=i;
    }
    
    sort(q+1,q+n+1,cmp2);
    
    for (i=2;i<=n;i++) 
      if ((a[q[i]]==a[q[i-1]])) down[q[i]]=1;
    
    for (i=1;i<=n;i++)
    {
        l=0;
        for (j=1;j<=n;j++) 
          if ((i!=j) && (a[q[j]]>=a[q[i]])) s[++l]=q[j];
          
        prep(q[i]);
    }
    
    sol=maxv;
    
    for (i=1;i<=n;++i)
      for (j=i+1;j<=n;++j) 
        {
           for (k=0;k<=n;++k) u[k]=v[k]=maxv;
        
           for (k=1;k<=n;++k)
               if ((k!=i) && (k!=j))
               {
                  x=nr(q[i],q[j],q[k]);
                  aux=arie(a[q[i]],a[q[j]],a[q[k]],b[q[i]],b[q[j]],b[q[k]]);
                  
                  if (aux>=0) 
                  {
                     if (aux<v[x]) v[x]=aux;
                  }
                  else if (-aux<u[x]) u[x]=-aux;
               }
              
           for (k=n-1;k>=0;--k) 
           {
               if (v[k+1]<v[k]) v[k]=v[k+1];
               if (u[k+1]<u[k]) u[k]=u[k+1];
           }             
         
           for (k=0;k<=m;++k) 
              if (v[k]+u[m-k]<sol) sol=v[k]+u[m-k];
         }
        
    printf("%.1lf\n",1.0*sol/2);
    
    return 0;
}