Cod sursa(job #119542)

Utilizator goguGogu Marian gogu Data 1 ianuarie 2008 21:06:03
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.47 kb
#include <cstdio>
#include <string.h>
#define pow(x) (1<<(x))
#define sqr(x) ((x)*(x))
#define dist(i, j) (sqr(x[i]-x[j]) + sqr(y[i]-y[j]))

int x[20], y[20], px[20], py[20], plus[20], n, nrpos;
int sol[1<<17][17];

inline void improve(int mask){
       #define W(j) if (!(mask & pow(j)) && sol[mask][i]+dist(i,j)<sol[mask+pow(j)][j]) \
                     sol[mask+pow(j)][j] = sol[mask][i]+dist(i,j);
     for (int i=0; i<n; i++)
         if (mask & pow(i)){
            W(0) W(1) W(2) W(3) W(4) W(5) W(6) W(7) W(8) W(9) W(10)
            W(10) W(11) W(12) W(13) W(14) W(15) W(16)
         }

}

void solve(){
     memset(sol, 0x7f, (17*4)<<n);
     for (int i=0; i<n; i++)
         for (int j=0; j<nrpos; j++)
             if (sqr(x[i]-px[j])+sqr(y[i]-py[j])+plus[j] < sol[pow(i)][i])
                sol[pow(i)][i] = sqr(x[i]-px[j])+sqr(y[i]-py[j])+plus[j];
     int last = (1<<n)-1;
     for (int mask=1; mask<last; mask++)
         improve(mask);
     nrpos = n;
     int min=sol[last][0];
     for (int i=0; i<n; i++){
         if (sol[last][i] < min) min = sol[last][i];
         px[i]=x[i], py[i]=y[i], plus[i] = sol[last][i];
     }
     printf("%d\n", min);
     n=0;
}

int main()
{
    freopen("bibel.in", "r", stdin);
    freopen("bibel.out", "w", stdout);
    nrpos=1;
    while (1){
          int op;
          scanf("%d", &op);
          if (op==0) scanf("%d %d", x+n, y+n), n++; else
          if (op==1) solve(); else return 0;
    }
}