/* Camelot (IOI 1998) Copyright (C) 2000 Sebastiano Vigna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Il problema viene risolto prima di tutto implementando un semplice algoritmo di calcolo del numero minimo di mosse per raggiungere una posizione. Il calcolo avviene per diffusione con scansioni globali successive (e` semplice da implementare e sufficientemente efficiente a causa della limitatissima dimensione delle scacchiere. Quindi le matrici delle distanze vengono combinate in vari modi cosi` da simulare i vari comportamenti possibili (nessun incontro, incontro con il cavaliere i per ogni i). */ #include #include #include #include #include #define min(a,b) ((a)<(b)?(a):(b)) #define MAXCAV 64 /* Massimo numero di cavalieri */ #define DIM 8 /* Dimensione della scacchiera */ int cavx[MAXCAV]; /* Ascissa iniziale dei cavalieri (tra 0 e 7) */ int cavy[MAXCAV]; /* Ordinata iniziale dei cavalieri (tra 0 e 7) */ int Dcav[MAXCAV][DIM][DIM]; /* Matrice delle distanze. D[i][j][k] e` il minimo numero di mosse di cui ha bisogno il cavaliere i per raggiungere la cella di coordinate j e k. */ int Dre[DIM][DIM]; /* Lo stesso per il re. */ int Drecav[DIM][DIM]; /* Lo stesso per il re in groppa a un cavallo. */ int T[DIM][DIM]; /* Matrice di comodo. */ /* Le otto mosse possibili per il re e per i cavalli (elencate in senso orario). */ #define NMOSSE 8 int mosse_re[NMOSSE][2] = { {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1} }; int mosse_cav[NMOSSE][2] = { {-2,1}, {-1,2}, {1,2}, {2,1}, {2,-1}, {1,-2}, {-1,-2}, {-2,-1} }; /* Questa funzione costruisce una matrice di distanze minime a partire da una posizione data. Inizialmente riempiamo la matrice con oo (infinito), e inizializziamo la posizione specificata con 0. Scandiamo ogni matrice alla fase d>=0 alla ricerca di elementi che hanno distanza d dalla posizione iniziale, e minimizziamo la distanza degli elementi raggiungibili dall'elemento trovato con d+1. La matrice delle mosse viene passata: in questo modo possiamo utilizzare questa funzione sia per il re che per i cavalieri. */ /* Macro di comodo per controllare se una posizione sta dentro la scacchiera. */ #define DENTRO(x,y) ((x)>=0 && (x)=0 && (y) d+1) { M[i+mosse[m][0]][j+mosse[m][1]] = d+1; fine = 0; /* Se abbiamo aggiunto qualcosa dobbiamo continuare! */ } } } d++; } while(!fine); } int main(int argc, char *argv[]) { char c, d; int i, j, k, p, q, rex, rey, ncav, mosse; /* Il re c'è sempre */ rex = getchar() - 'A'; rey = getchar() - '1'; /* Andiamo ora a leggere due caratteri per cavaliere. Alla fine ncav conterra` il numero di cavalieri. */ ncav = 0; while(scanf("%c%c ", &c, &d) != EOF) { cavx[ncav] = c - 'A'; cavy[ncav] = d - '1'; ncav++; } /* Costruiamo le matrici delle distanze. */ distmin(Dre, rex, rey, mosse_re); for(i=0; i e` Dre[j][k] + Dcav[i][j][k]. Quindi per sapere il costo minimo in mosse per raggiungere una posizione dobbiamo minimizzare su tutti i possibili punti di incontro il numero di mosse necessario al re e al cavallo (separatamente) per raggiungere e il numero di mosse necessarie per raggiungere da (insieme). */ for(j=0; j. */ for(p=0; p insieme. Sommando la matrice Drecav con tutte le Dcav (tranne quella di indice i) otteniamo una matrice che da` il numero globale di mosse necessarie per raggiungere le varie posizioni della scacchiera se il cavaliere i si prende in groppa il re.*/ for(j=0; j