#include #define MAXN 100 #define MOC 0x1000000 #define MAX(a, b) ((a) < (b) ? (b) : (a)) int n; int vyska[MAXN][MAXN]; int hladina[MAXN][MAXN]; struct { int i,j; int hladina; /* kopie hladina[i][j]*/ } halda[MAXN*MAXN]; int hlen = 0; int smery[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; void swap (int p1, int p2) { int p; #define SWAP(x, y) ( p = (x), (x) = (y), (y) = p ) SWAP (halda[p1].i, halda[p2].i); SWAP (halda[p1].j, halda[p2].j); SWAP (halda[p1].hladina, halda[p2].hladina); } void extractMin () { int p; if (hlen < 2) { hlen = 0; return; } swap (1, hlen); hlen --; p = 1; while (2 * p <= hlen) { int k = 2 * p; if (k + 1 <= hlen && halda[k].hladina > halda[k + 1].hladina) k ++; if (halda[p].hladina <= halda[k].hladina) break; swap (p, k); p = k; } } void add (int i, int j) { int p; p = ++ hlen; halda[hlen].i = i; halda[hlen].j = j; halda[hlen].hladina = hladina[i][j]; while (p > 1) { int k = p / 2; if (halda[k].hladina <= halda[p].hladina) break; swap (p, k); p = k; } } int spocti () { int objem = 0; int i, j; for (i = 0; i < n; i++) for (j = 0; j < n; j++) hladina[i][j] = MOC; /* pridej kraje */ for (i = 0; i < n; i++) { hladina[i][0] = MAX (0, vyska[i][0]); add (i, 0); hladina[i][n - 1] = MAX (0, vyska[i][n - 1]); add (i, n - 1); } for (j = n - 1; j > 0; j--) { hladina[0][j] = MAX (0, vyska[0][j]); add (0, j); hladina[n - 1][j] = MAX (0, vyska[n - 1][j]); add (n - 1, j); } while (hlen > 0) { int i = halda[1].i; int j = halda[1].j; int h = halda[1].hladina; int k; extractMin (); for (k = 0; k < 4; k++) { int ii = i + smery[k][0]; int jj = j + smery[k][1]; if (ii >= n || ii < 0 || jj >= n || jj < 0) continue; /* mimo matici */ if (hladina[ii][jj] != MOC) continue; /* uz nastaveno */ hladina[ii][jj] = MAX (h, vyska[ii][jj]); add (ii, jj); } } /* spocti objem */ /* cele pole hladina a tento vypocet by se daly vyhodit, ale takhle * je to prehlednejsi...*/ for (i = 0; i < n; i++) for (j = 0; j < n; j++) objem += hladina[i][j] - vyska[i][j]; return objem; } void nacti () { int i,j; scanf ("%d", &n); for (i = 0; i < n; i++) for (j = 0; j < n; j++) scanf ("%d", vyska[i] + j); } int main () { int objem; nacti (); if (n < 2) objem = 0; /* trivialni pripady, ktere by delaly problem */ else objem = spocti (); printf ("Mnozstvi zadrzene vody je %d\n", objem); return 0; }