Cod sursa(job #600039)

Utilizator nandoLicker Nandor nando Data 30 iunie 2011 13:33:57
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;

//<parsing>
FILE* fin=fopen("struti.in","r");
const unsigned maxb=8192;
char buf[maxb];
unsigned ptr=0;

inline unsigned getInt(){
	unsigned nr=0;
	while(buf[ptr]<'0'||'9'<buf[ptr])
		if(++ptr>=maxb)
			fread(buf,maxb,1,fin),ptr=0;
	while('0'<=buf[ptr]&&buf[ptr]<='9'){
		nr=nr*10+buf[ptr]-'0';
		if(++ptr>=maxb)
			fread(buf,maxb,1,fin),ptr=0;
	}
	return nr;
}
//</parsing>

fstream fout ("struti.out", ios::out);

#define INF 0x3f3f3f3f
#define MAXN 1010

int n, m, q, x, y;
int mat[MAXN][MAXN], matV[2][MAXN][MAXN], matH[2][MAXN][MAXN];
int mn, nmin;

void horz (bool (*cmp) (int, int), int idx, int k)
{
    for (int i = 0; i < n; ++i) {
        deque <int> d;

        for (int j = 0; j < m; ++j) {
            while (!d.empty () && cmp (mat[i][d.back ()], mat[i][j])) {
                d.pop_back ();
            }
            d.push_back (j);

            if (d.front () == j - k) {
                d.pop_front ();
            }

            if (j >= k - 1) {
                matH[idx][i][j] = mat[i][d.front ()];
            }
        }
    }
}

void vert (bool (*cmp) (int, int), int idx, int k)
{
    for (int i = 0; i < m; ++i) {
        deque <int> d;

        for (int j = 0; j < n; ++j) {
            while (!d.empty () && cmp (matH[idx][d.back ()][i], matH[idx][j][i])) {
                d.pop_back ();
            }
            d.push_back (j);

            if (d.front () == j - k) {
                d.pop_front ();
            }

            if (j >= k - 1) {
                matV[idx][j][i] = matH[idx][d.front ()][i];
            }
        }
    }
}

bool minC (int a, int b) {return a > b;};
bool maxC (int a, int b) {return a < b;};
int abs (int a) {return a > 0 ? a : -a;};

void combine (int sx, int sy)
{
    for (int i = sy - 1; i < n; ++i) {
        for (int j = sx - 1; j < m; ++j) {
            int cm = abs (matV[1][i][j] - matV[0][i][j]);

            if (cm < mn) {
                mn = cm, nmin = 1;
            } else if (cm == mn) {
                nmin ++;
            }
        }
    }
}

void doTest ()
{
    x = getInt (), y = getInt ();

    horz (minC, 0, x);
    horz (maxC, 1, x);
    vert (minC, 0, y);
    vert (maxC, 1, y);

    mn = INF, nmin = 0;
    combine (x, y);

    if (x != y) {
        horz (minC, 0, y);
        horz (maxC, 1, y);
        vert (minC, 0, x);
        vert (maxC, 1, x);

        combine (y, x);
    }

    fout << mn << " " << nmin << '\n';
}

int main ()
{
    n = getInt (), m = getInt (), q = getInt ();

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            mat[i][j] = getInt ();
        }
    }

    for (int i = 0; i < q; ++i) {
        doTest ();
    }

    fclose (fin);
    fout.close ();
    return 0;
}