Cod sursa(job #1099385)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 5 februarie 2014 20:06:33
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <deque>
#include <cstring>

using namespace std;

ifstream fin("struti.in");
ofstream fout("struti.out");

const int Nmax = 1010;
const int oo = 0x3f3f3f3f;

struct Poz_Val{
    int p, v;
}E;

int N, M, P, cnt, A[Nmax][Nmax];
deque <Poz_Val> DLM, DLm, DCM[Nmax], DCm[Nmax];

int Solve(int X, int Y)
{
    if(X > N || Y > M) return 0;

    int BEST = oo;
    for(int j = 1; j <= M; j++)
        DCM[j].clear(), DCm[j].clear();

    for(int j = 1; j <= M; j++)
        for(int i = 1; i < X; i++)
        {
            E.v = A[i][j]; E.p = i;
            while(!DCM[j].empty() && DCM[j].back().v <= E.v)
                DCM[j].pop_back();
            while(!DCm[j].empty() && DCm[j].back().v >= E.v)
                DCm[j].pop_back();

            DCM[j].push_back(E);
            DCm[j].push_back(E);
        }

    for(int i = X; i <= N; i++)
    {
        DLM.clear(); DLm.clear();
        for(int j = 1; j <= M; j++)
        {
            E.v = A[i][j]; E.p = i;
            while(!DCM[j].empty() && DCM[j].back().v <= E.v)
                DCM[j].pop_back();
            DCM[j].push_back(E);

            while(!DCm[j].empty() && DCm[j].back().v >= E.v)
                DCm[j].pop_back();
            DCm[j].push_back(E);

            if(DCM[j].front().p <= i - X)
                DCM[j].pop_front();
            if(DCm[j].front().p <= i - X)
                DCm[j].pop_front();

            E.v = DCM[j].front().v; E.p = j;
            while(!DLM.empty() && DLM.back().v <= E.v)
                DLM.pop_back();
            DLM.push_back(E);

            E.v = DCm[j].front().v; E.p = j;
            while(!DLm.empty() && DLm.back().v >= E.v)
                DLm.pop_back();
            DLm.push_back(E);

            if(DLM.front().p <= j - Y)
                DLM.pop_front();
            if(DLm.front().p <= j - Y)
                DLm.pop_front();

            if(j >= Y)
            {
                int dif = DLM.front().v - DLm.front().v;
                if(dif < BEST) BEST = dif, cnt = 1;
                else if(dif == BEST) cnt++;
            }
        }
    }
    return BEST;
}

int main()
{
    fin >> N >> M >> P;
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            fin >> A[i][j];
    while(P--)
    {
        int DX, DY, rez1 = oo, rez2 = oo, fr1, fr2;
        fin >> DX >> DY;
        rez1 = Solve(DX, DY); fr1 = cnt;
        if(DX != DY) rez2 = Solve(DY, DX); fr2 = cnt;

        if(rez1 < rez2)
            fout << rez1 << ' ' << fr1;
        else if(rez2 < rez1)
            fout << rez2 << ' ' << fr2;
        else
            fout << rez1 << ' ' << fr1 + fr2;
        fout << '\n';
    }
    return 0;
}