/* Punteggio (Score, IOI 2001) Copyright (C) 2002 Paolo Boldi 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, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (Come per tutti i problemi del 2001, è utile leggere il libretto distribuito dagli organizzatori, e disponibile nella sezione "Materiale didattico" della home page http://ioi.dsi.unimi.it/. Inoltre, per fare gareggiare due programmi potete utilizzare il referee che trovate su http://ioi.dsi.unimi.it/problemi/) Per capire come funziona questo programma, è necessario prima leggere la dispensa sulla teoria dei giochi che trovate su http://ioi.dsi.unimi.it/. Il programma esplora le possibili configurazioni del gioco (che viene, in effetti, descritto direttamente tramite la matrice di adiacenza delle sue configurazioni) e calcola ricorsivamente, per ciascuna posizione, il punteggio finale ottenibile da ciascun giocatore a partire da quella posizione se entrambi i giocatori giocano in modo ottimale, cioè con lo scopo di massimizzare la differenza fra il loro punteggio e quello dell'avversario. OPZIONI DI COMPILAZIONE (gcc) - Compilare con -DALTRO per giocare come il giocatore 2 (altrimenti si gioca come 1). - Compilare con -DDEBUG per avere in output, alla fine, il punteggio realizzato dai due giocatori (su stderr). */ #include #include #define MAXN 1000 #ifdef ALTRO #define MESTESSO 1 #else #define MESTESSO 0 #endif /* NB: le posizioni sono numerate da 0 a N-1, i giocatori da 0 a 1 (0=io, 1=avversario). */ int N; /* Il valore di N */ int propr[MAXN]; /* propr[i]=0 oppure 1 */ int valore[MAXN]; /* valore[i] è il valore della posizione i */ int A[MAXN][MAXN]; /* A[i][j] iff da i si va a j */ /* Dopo aver invocato la funzione valuta, i seguenti vettori contengono: ott[pos][i] il miglior valore ottenibile dal giocatore i se si parte dalla posizione pos assumendo che entrambi giochino in modo ottimale mossa[pos] la mossa ottimale per il giocatore propr[pos] nella posizione pos */ int ott[MAXN][2]; int mossa[MAXN]; /* Dopo averla invocata, per ogni posizione p raggiungibile da pos è garantito che ott[p][...] e mossa[p] contengano valori corretti. Se primamossa=1 vuol dire che nessun giocatore ha ancora mosso */ void valuta( int pos, int primamossa ) { int prosspos, prossott, diff; if ( mossa[pos] >= 0 ) return; /* Posizione gia` valutata */ ott[pos][0] = ott[pos][1] = 0; ott[pos][propr[pos]] = valore[pos]; if ( pos == 0 && !primamossa ) return; /* Gioco finito */ prossott = -INT_MAX; for ( prosspos = 0; prosspos < N; prosspos++ ) if ( A[pos][prosspos] ) { valuta( prosspos, 0 ); diff = ott[prosspos][propr[pos]] - ott[prosspos][1-propr[pos]]; if ( diff > prossott ) { prossott = diff; mossa[pos] = prosspos; } } if ( ott[mossa[pos]][0] > ott[pos][0] ) ott[pos][0] = ott[mossa[pos]][0]; if ( ott[mossa[pos]][1] > ott[pos][1] ) ott[pos][1] = ott[mossa[pos]][1]; } /* Lettura input */ void readin() { int i,j; scanf( "%d", &N ); for ( i = 0; i < N; i++ ) for ( j = 0; j < N; j++ ) scanf( "%d", &A[i][j] ); for ( i = 0; i < N; i++ ) { scanf( "%d", &propr[i] ); propr[i]--; } for ( i = 0; i < N; i++ ) { scanf( "%d", &valore[i] ); mossa[i] = -1; } } int main() { int pos, primamossa; #ifdef DEBUG int ottcorr[2]; #endif readin(); valuta( 0, 1 ); pos = 0; #ifdef DEBUG ottcorr[0] = ottcorr[1] = 0; #endif primamossa = 1; do { if ( propr[pos] != MESTESSO ) { scanf( "%d", &pos ); pos--; } else { printf( "%d\n", ( pos = mossa[pos] )+1 ); fflush(stdout); } #ifdef DEBUG if ( valore[pos]>ottcorr[propr[pos]] ) ottcorr[propr[pos]]=valore[pos]; #endif primamossa = 0; } while ( pos ); #ifdef DEBUG fprintf( stderr, "Player %d: %d, Player %d: %d\n", MESTESSO, ottcorr[MESTESSO], 1-MESTESSO, ottcorr[1-MESTESSO] ); fflush(stderr); #endif return 0; }