/* Frog (IOI 2002) Copyright (C) 2002 Paolo Boldi, Stefano Maggiolo and 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 Le piante schiacciate vengono memorizzate sia nella matrice rappresentante il campo che in un array, che viene ordinato in base alla coordinata x e, a parità di questa, alla coordinata y; vengono poi provate le coppie in cui il primo elemento è strettamente minore del secondo nell'ordinamento fatto in precedenza, per garantire che se le due piante fanno parte di un cammino, la prima della coppia debba essere anche la prima del cammino. Questa considerazione porta a tagliare il calcolo per quei cammini che dovrebbero avere un ulteriore punto precedente al primo della coppia, perché, se ci fosse, sarebbe gia` stato provato in precedenza. Inoltre, date le distanze tra due piante schiacciate del possibile cammino, possiamo stabilire il numero di piante calpestate dalla rana, e ovviamente se questo è minore o uguale del massimo finora trovato, possiamo evitare di controllare che sia un cammino valido e passare al successivo. Se ciò non succedesse, si passerebbe a controllare che tutti i punti di atterraggio siano effettivamente calpestati; in caso affermativo, si aggiorna il massimo ottenuto. */ #include #include #define MAXR 5000 #define MAXC 5000 #define MAXN 5000 int R,C; int N; char f[MAXR][MAXC]; struct intersezione { int x,y; } u[MAXN]; void read() { int i; scanf("%d %d", &R, &C); scanf("%d", &N); for (i = 0; i < N; i++) { scanf( "%d %d", &(u[i].y), &(u[i].x) ); f[--u[i].x][--u[i].y] = 1; } } /* le coppie vengono ordinate prima per x e poi per y */ int comp( const void *a, const void *b ) { const struct intersezione *aa = (const struct intersezione *)a, *bb = (const struct intersezione *)b; if (aa->x - bb->x != 0) return aa->x - bb->x; return aa->y - bb->y; } void scan() { int i, j, dx, dy, c, max, x, y; /* vengono ignorati i cammini minori di 3 punti */ max = 2; /* si provano tutte le coppie */ for (i = 0; i < N; i++) for (j = i+1; j < N; j++) { /* solo se non ci deve essere un altro punto del cammino precedente ad i */ if (u[i].x < u[j].x - u[i].x || u[i].y < u[j].y - u[i].y) { dx = u[j].x - u[i].x; dy = u[j].y - u[i].y; /* la lunghezza del cammino è il minimo tra i due rapporti lunghezza su scostamento */ if ((dx != 0 && C / dx + 1 <= max) || (dy != 0 && R / abs(dy) + 1 <= max)) continue; /* il ciclo controlla che tutte le altre piante del cammino siano schiacciate */ x = u[i].x; y = u[i].y; c = 0; while (x >= 0 && x < C && y >= 0 && y < R) { if (!f[x][y]) { c = -1; break; } c++; x += dx; y += dy; } if (c > max) max = c; } } /* se il massimo è rimasto due, non c'e` alcun percorso di rane */ if (max > 2) printf("%d\n", max); else puts( "0" ); } int main() { read(); qsort( u, N, sizeof *u, comp ); scan(); return 0; }