Cod sursa(job #2055407)

Utilizator borscalinCalin-Stefan Georgescu borscalin Data 3 noiembrie 2017 10:36:18
Problema Struti Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.28 kb
#include <stdio.h>
#include <stdlib.h>
#define NMAX 1000
#define INF 8001
#define mins(a, b) (a > b) ? b : a
#define maxs(a, b) (a > b) ? a : b

#define D 0

int a[1 + NMAX][1 + NMAX];
int matmin[1 + NMAX][1 + NMAX];
int matmax[1 + NMAX][1 + NMAX];
int dmin[1 + NMAX];
int dmax[1 + NMAX];
int n, m, sol, ap;

void minim(int k) {
    for (int y = 1; y <= m; ++y) {
        int d[1 + k];
        int st = 0, dr = -1;
        for (int x = 0; x <= n; ++x)
            d[y] = INF;
        for (int x = 1; x <= n; ++x) {
            if (st <= dr && d[st] == x - k)
                ++st;
            while (st <= dr && a[d[dr]][y] >= a[x][y])
                --dr;
            d[++dr] = x;
            matmin[x][y] = a[d[st]][y];
        }

    }
}

void maxim(int k) {
    for (int y = 1; y <= m; ++y) {
        int d[1 + k];
        int st = 0, dr = -1;
        for (int x = 0; x <= n; ++x)
            d[y] = 0;
        for (int x = 1; x <= n; ++x) {
            if (st <= dr && d[st] == x - k)
                ++st;
            while (st <= dr && a[d[dr]][y] <= a[x][y])
                --dr;
            d[++dr] = x;
            matmax[x][y] = a[d[st]][y];
        }

    }
}

void reset() {
    for (int x = 1; x <= n; ++x)
        for (int y = 1; y <= m; ++y)
            matmin[x][y] = INF;
    for (int x = 1; x <= n; ++x)
        for (int y = 1; y <= m; ++y)
            matmax[x][y] = 0;
}

void solve(int dx, int dy) {
    for (int x = dx; x <= n; ++x) {
        int stmin = 0, stmax = 0;
        int drmin = -1, drmax = -1;
        for (int y = 1; y <= m; ++y) {
            if (stmin <= drmin && dmin[stmin] == y - dy)
                ++stmin;
            if (stmax <= drmax && dmax[stmax] == y - dy)
                ++stmax;
            while (stmin <= drmin && matmin[x][dmin[drmin]] >= matmin[x][y])
                --drmin;
            while (stmax <= drmax && matmax[x][dmax[drmax]] <= matmax[x][y])
                --drmax;
            dmin[++drmin] = y;
            dmax[++drmax] = y;
            if (y >= dy) {
                int val = matmax[x][dmax[stmax]] - matmin[x][dmin[stmin]];
                if (val < sol)
                    sol = val, ap = 1;
                else if (val == sol)
                    ++ap;
            }
        }
    }
}
int main(){
    int p, dx, dy;
    FILE *fin = fopen("struti.in", "r");
    fscanf(fin, "%d%d%d", &n, &m, &p);
    for (int x = 1; x <= n; ++x)
        for (int y = 1; y <= m; ++y)
            fscanf(fin, "%d", &a[x][y]);
    FILE *fout = fopen("struti.out", "w");
    for (int i = 1; i <= p; ++i) {
        fscanf(fin, "%d%d", &dx, &dy);
        sol = INF + 1;
        ap = 0;
        minim(dx);
        maxim(dx);
        if (D == 1) {
            for (int d1 = 1; d1 <= n; ++d1) {
                for (int d2 = 1; d2 <= m; ++d2)
                    printf("%d ", matmin[d1][d2]);
                printf("\n");
            }
            for (int d1 = 1; d1 <= n; ++d1) {
                for (int d2 = 1; d2 <= m; ++d2)
                    printf("%d ", matmax[d1][d2]);
                printf("\n");
            }
        }
        solve(dx, dy);
        reset();
        if(dx != dy) {
            minim(dy);
            maxim(dy);
            solve(dy, dx);
            reset();
        }
        fprintf(fout, "%d %d\n", sol, ap);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}