Cod sursa(job #1255899)

Utilizator SmarandaMaria Pandele Smaranda Data 5 noiembrie 2014 15:16:28
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.37 kb
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 1004;

int n, m, p;
int a [N][N], minD [N], maxD [N], minim1 [N][N], maxim1 [N][N], minim2 [N][N], maxim2 [N][N] ;

int condition (const bool &ct, const int &i, const int &j, int x[][N]) {
    if (ct == 0)
        return x [i][j];
    return x [j][i];
}

void minDeque (const int &k, const int &lim, const int &l, bool ct, int x[][N]) {
    int p, u, i, h = 0;

    if (l == 1) {
        for (i = 1; i <= lim; i ++)
            if (ct == 0)
                minim1 [k][++ h] = x [k][i];
            else minim2 [++ h][k] = x [i][k];
        return;
    }

    p = u = 1;
    minD [1] = 1;
    i = 2;
    while (i <= lim) {
        while (p <= u && condition (ct, k, i, x) <= condition (ct, k, minD [u], x))
            u --;
        minD [++ u] = i;
        if (i >= l) {
            if (ct == 0)
                minim1 [k][++ h] = x [k][minD [p]];
            else minim2 [++ h][k] = x [minD [p]][k];
            if (i + 1 - minD [p] + 1 > l)
                p ++;
        }
        ++ i;
    }
}

void maxDeque (const int &k, const int &lim, const int &l, bool ct, int x[][N]) {
    int p, u, i, h = 0;

    if (l == 1) {
        for (i = 1; i <= lim; i ++) {
            if (ct == 0)
                maxim1 [k][++ h] = x [k][i];
            else maxim2 [++ h][k] = x [i][k];
        }
        return;
    }

    p = u = 1;
    maxD [1] = 1;
    i = 2;
    while (i <= lim) {
        while (p <= u && condition (ct, k, i, x) >= condition (ct, k, maxD [u], x))
            u --;
        maxD [++ u] = i;
        if (i >= l) {
            if (ct == 0)
                maxim1 [k][++ h] = x [k][maxD [p]];
            else maxim2 [++ h][k] = x [maxD [p]][k];
             if (i + 1 - maxD [p] + 1 > l)
                p ++;
        }
         ++ i;
    }
}

int solve (int x, int y, int &num) {
    int i, limn, limm, ans, j;

    limn = n - x + 1;
    limm = m - y + 1;
    ans = (1ll << 31) - 1;
    // linii
    for (i = 1; i <= n; i ++) {
        minDeque (i, m, y, 0, a);
        maxDeque (i, m, y, 0, a);
    }
    // coloane
    for (i = 1; i <= limm; i ++) {
        minDeque (i, n, x, 1, minim1);
        maxDeque (i, n, x, 1, maxim1);
    }
    for (i = 1; i <= limn; i ++)
        for (j = 1; j <= limm;j ++) {
            minim1 [i][j] = maxim2 [i][j] - minim2 [i][j];
            if (minim1 [i][j] < ans) {
                ans = minim1 [i][j];
                num = 1;
            }
            else
                if (minim1 [i][j] == ans)
                    num ++;
        }
    return ans;
}

int main () {
    int i, j, x, y, dif1, num1, dif2, num2, ans, num;

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

    scanf ("%d%d%d", &n, &m, &p);
    for (i = 1; i <= n; i ++)
        for (j = 1; j <= m; j ++)
            scanf ("%d", &a [i][j]);
    for (i = 1; i <= p; i ++) {
        scanf ("%d%d", &x, &y);
        dif1 = solve (x, y, num1);
        dif2 = solve (y, x, num2);
        ans = dif1;
        num = num1;
        if (dif2 < ans) {
            ans = dif2;
            num = num2;
        }
        else
            if (dif2 == ans && x != y)
                num = num + num2;
        printf ("%d %d\n", ans, num);
        memset (minim1, 0, sizeof (minim1));
        memset (minim2, 0, sizeof (minim2));
        memset (maxim1, 0, sizeof (maxim1));
        memset (maxim2, 0, sizeof (maxim2));
    }
    return 0;
}