Cod sursa(job #2055393)

Utilizator borscalinCalin-Stefan Georgescu borscalin Data 3 noiembrie 2017 10:31:11
Problema Struti Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.3 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;

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;
}

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");
    int sol, ap;
    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");
            }
        }
        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;
                }
            }
        }
        reset();
        if(dx != dy) {
            minim(dy);
            maxim(dy);
            for (int x = dy; 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 - dx)
                        ++stmin;
                    if (stmax <= drmax && dmax[stmax] == y - dx)
                        ++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 >= dx) {
                        int val = matmax[x][dmax[stmax]] - matmin[x][dmin[stmin]];
                        if (val < sol)
                            sol = val, ap = 1;
                        else if (val == sol)
                            ++ap;
                    }
                }
            }
            reset();
        }
        fprintf(fout, "%d %d\n", sol, ap);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}