#include #include #define MAX_N 200 #define INFINITY 65535 int m, n; // Matricea înălțimilor, bordată cu înălțimi infinite unsigned short h[MAX_N + 2][MAX_N + 2]; // partr[i][j] = numărul de clădiri >= alt în segmentul (i,j)-(i,j+size-1) unsigned char partr[MAX_N + 2][MAX_N + 2]; // partc[i][j] = numărul de clădiri >= alt în segmentul (i,j)-(i+size-1,j) unsigned char partc[MAX_N + 2][MAX_N + 2]; // reach[i][j] = 1 dacă nava curentă poate ajunge cu centrul în (i, j) char reach[MAX_N + 1][MAX_N + 1]; // count[i][j] reține numărul de nave care pot ajunge în (i, j) char count[MAX_N + 1][MAX_N + 1]; // Numărul și raza OZN-ului curent -- pentru un fill mai rapid int ufo, radius; void partialSums(int altitude, int size) { for (int i = 0; i <= m + 1; i++) { partr[i][1] = 0; for (int j = 1; j <= size; j++) { partr[i][1] += (h[i][j] >= altitude); } for (int j = 2; j <= n - size + 1; j++) { partr[i][j] = partr[i][j - 1] - (h[i][j - 1] >= altitude) + (h[i][j + size - 1] >= altitude); } } for (int j = 0; j <= n + 1; j++) { partc[0][j] = 0; for (int i = 0; i < size; i++) { partc[0][j] += (h[i][j] >= altitude); } for (int i = 1; i <= m + 2 - size; i++) { partc[i][j] = partc[i - 1][j] - (h[i - 1][j] >= altitude) + (h[i + size - 1][j] >= altitude); } } } /* Scrie valoarea ufo în toate pătratele în care putem plasa centrul navei. */ void fill(int i, int j) { if (reach[i][j] == ufo) { return; } reach[i][j] = ufo; if (!partr[i - radius - 1][j - radius]) { fill(i - 1, j); } if (!partc[i - radius][j + radius + 1]) { fill(i, j + 1); } if (!partr[i + radius + 1][j - radius]) { fill(i + 1, j); } if (!partc[i - radius][j - radius - 1]) { fill(i, j - 1); } } int main(void) { int numUfos; FILE *f = fopen("ozn.in", "r"); // Citește matricea de înălțimi fscanf(f, "%d %d %d", &m, &n, &numUfos); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { fscanf(f, "%hu", &h[i][j]); } } // Bordează matricea de înălțimi for (int i = 1; i <= m; i++) { h[i][0] = h[i][n + 1] = INFINITY; } for (int j = 1; j <= n; j++) { h[0][j] = h[m + 1][j] = INFINITY; } for (ufo = 1; ufo <= numUfos; ufo++) { // Citește un OZN int row, col, size, altitude; fscanf(f, "%d %d %d %d", &row, &col, &size, &altitude); // Din acest moment, matricea este privită binar: elemente sub alt (0) și elemente >= alt (1). // Precalculăm pe ea sume parțiale ca să putem testa rapid vecinătatea în fill(). partialSums(altitude, size); // Calculează matricea punctelor în care pot ajunge radius = size / 2; fill(row, col); // Adună rezultatul la total for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { count[i][j] += (reach[i][j] == ufo); } } } fclose(f); // Calculează numărul punctelor de întâlnire posibile int answer = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { answer += (count[i][j] == numUfos); } } f = fopen("ozn.out", "w"); fprintf(f, "%d\n", answer); fclose(f); }