Cod sursa(job #841432)

Utilizator stoicatheoFlirk Navok stoicatheo Data 24 decembrie 2012 10:45:19
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.7 kb
#include<cstdio>

const int N = 1002;
const int S = 5000;

int m, n, p, a[N][N], cmax[N][N], cmin[N][N], min[N][N], max[N][N], mmin, aparitii;
char s[S];

inline bool cif(char c) {
    return ('0' <= c && c <= '9');
}

void citire() {
    scanf("%d%d%d\n", &m, &n, &p);

    for (int i = 1; i <= m; ++i) {
        gets(s);

        int poz = 0;
        for (int j = 1; j <= n; ++j) {
            while (cif(s[poz])) {
                a[i][j] = a[i][j] * 10 + s[poz] - '0';
                ++poz;
            }

            ++poz;
        }
    }
}

void dequemin(int lin, int k) {
    int st = 1, dr = 0, poz[N];
    poz[0] = 0;

    for (int j = 1; j <= k; ++j) {
        while (st <= dr && a[lin][poz[dr]] >= a[lin][j])
            --dr;

        poz[++dr] = j;
    }

    cmin[lin][k] = a[lin][poz[st]];

    for (int j = k + 1; j <= n; ++j) {
        while (st <= dr && a[lin][poz[dr]] >= a[lin][j])
            --dr;

        poz[++dr] = j;

        while (j - poz[st] >= k)
            ++st;

        cmin[lin][j] = a[lin][poz[st]];
    }
}

void dequemax(int lin, int k) {
    int st = 1, dr = 0, poz[N];
    poz[0] = 0;

    for (int j = 1; j <= k; ++j) {
        while (st <= dr && a[lin][poz[dr]] <= a[lin][j])
            --dr;

        poz[++dr] = j;
    }

    cmax[lin][k] = a[lin][poz[st]];

    for (int j = k + 1; j <= n; ++j) {
        while (st <= dr && a[lin][poz[dr]] <= a[lin][j])
            --dr;

        poz[++dr] = j;

        while (j - poz[st] >= k)
            ++st;

        cmax[lin][j] = a[lin][poz[st]];
    }
}

void deqcolmin(int dx, int k) {
    for (int j = dx; j <= n; ++j) {
        int st = 1, dr = 0, poz[N];
        poz[0] = 0;

        for (int i = 1; i <= k; ++i) {
            while (st <= dr && cmin[poz[dr]][j] >= cmin[i][j])
                --dr;

            poz[++dr] = i;
        }

        min[k][j] = cmin[poz[st]][j];

        for (int i = k + 1; i <= m; ++i) {
            while (st <= dr && cmin[poz[dr]][j] >= cmin[i][j])
                --dr;

            poz[++dr] = i;

            while (i - poz[st] >= k)
                ++st;

            min[i][j] = cmin[poz[st]][j];
        }
    }
}

void deqcolmax(int dx, int k) {
    for (int j = dx; j <= n; ++j) {
        int st = 1, dr = 0, poz[N];
        poz[0] = 0;

        for (int i = 1; i <= k; ++i) {
            while (st <= dr && cmax[poz[dr]][j] <= cmax[i][j])
                --dr;

            poz[++dr] = i;
        }

        max[k][j] = cmax[poz[st]][j];

        for (int i = k + 1; i <= m; ++i) {
            while (st <= dr && cmax[poz[dr]][j] <= cmax[i][j])
                --dr;

            poz[++dr] = i;

            while (i - poz[st] >= k)
                ++st;

            max[i][j] = cmax[poz[st]][j];
        }
    }
}

void rez(int dx, int dy) {
    for (int i = 1; i <= m; ++i) {
        dequemin(i, dx);
        dequemax(i, dx);
    }

    deqcolmin(dx, dy);
    deqcolmax(dx, dy);

    for (int i = dy; i <= m; ++i)
        for (int j = dx; j <= n; ++j)
            if (max[i][j] - min[i][j] < mmin) {
                mmin = max[i][j] - min[i][j];
                aparitii = 1;
            }
            else
            if (max[i][j] - min[i][j] == mmin)
                ++aparitii;
}

int main() {
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);

    citire();

    for (int i = 1; i <= p; ++i) {
        int dx, dy;
        scanf("%d%d", &dx, &dy);

        mmin = 8005;
        aparitii = 0;

        rez(dx, dy);

        if (dy != dx)
            rez(dy, dx);

        printf("%d %d\n", mmin, aparitii);
    }

    return 0;
}