Cod sursa(job #598990)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 27 iunie 2011 18:16:32
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.77 kb
#include <iostream>
#include <fstream>
#include <deque>

#define Infinit 1000000000

using namespace std;

typedef struct
{
    int Min;
    int Max;
}
Matrice;

deque <int> DMin, DMax;
int N, M, Teren[1005][1005], S, NS;
Matrice Linii[1005][1005], Final[1005][1005];

void CalculLinii (int K)
{
    for (int i=1; i<=N; ++i)
    {
        DMin.clear ();
        DMax.clear ();
        for (int j=1; j<=M; ++j)
        {
            while (!DMin.empty () and Teren[i][DMin.back ()]>=Teren[i][j])
            {
                DMin.pop_back ();
            }
            DMin.push_back (j);
            if (DMin.front ()<=j-K)
            {
                DMin.pop_front ();
            }
            if (j>=K)
            {
                Linii[i][j].Min=Teren[i][DMin.front ()];
            }
            else
            {
                Linii[i][j].Min=-Infinit;
            }
            while (!DMax.empty () and Teren[i][DMax.back ()]<=Teren[i][j])
            {
                DMax.pop_back ();
            }
            DMax.push_back (j);
            if (DMax.front ()<=j-K)
            {
                DMax.pop_front ();
            }
            if (j>=K)
            {
                Linii[i][j].Max=Teren[i][DMax.front ()];
            }
            else
            {
                Linii[i][j].Max=Infinit;
            }
        }
    }
}

void CalculColoane (int K, int Start)
{
    for (int i=1; i<=N; ++i)
    {
        for (int j=1; j<Start; ++j)
        {
            Final[i][j].Min=-Infinit;
            Final[i][j].Max=Infinit;
        }
    }
    for (int j=Start; j<=M; ++j)
    {
        DMin.clear ();
        DMax.clear ();
        for (int i=1; i<=N; ++i)
        {
            while (!DMin.empty () and Linii[DMin.back ()][j].Min>=Linii[i][j].Min)
            {
                DMin.pop_back ();
            }
            DMin.push_back (i);
            if (DMin.front ()<=i-K)
            {
                DMin.pop_front ();
            }
            if (i>=K)
            {
                Final[i][j].Min=Linii[DMin.front ()][j].Min;
            }
            else
            {
                Final[i][j].Min=-Infinit;
            }
            while (!DMax.empty () and Linii[DMax.back ()][j].Max<=Linii[i][j].Max)
            {
                DMax.pop_back ();
            }
            DMax.push_back (i);
            if (DMax.front ()<=i-K)
            {
                DMax.pop_front ();
            }
            if (i>=K)
            {
                Final[i][j].Max=Linii[DMax.front ()][j].Max;
            }
            else
            {
                Final[i][j].Max=Infinit;
            }
        }
    }
}

void Seek (int DX, int DY)
{
    for (int i=DX; i<=N; ++i)
    {
        for (int j=DY; j<=M; ++j)
        {
            if (Final[i][j].Max-Final[i][j].Min==S)
            {
                NS++;
            }
            if (Final[i][j].Max-Final[i][j].Min<S)
            {
                S=Final[i][j].Max-Final[i][j].Min;
                NS=1;
            }
        }
    }
}

int main()
{
    ifstream fin ("struti.in");
    ofstream fout ("struti.out");
    int NQ, DX, DY;
    fin >> N >> M >> NQ;
    for (int i=1; i<=N; ++i)
    {
        for (int j=1; j<=M; ++j)
        {
            fin >> Teren[i][j];
        }
    }

    for (; NQ>0; --NQ)
    {
        fin >> DX >> DY;
        S=Infinit;
        CalculLinii (DY);
        CalculColoane (DX, DY);
        Seek (DX, DY);
        if (DX!=DY)
        {
            CalculLinii (DX);
            CalculColoane (DY, DX);
            Seek (DY, DX);
        }
        fout << S << " " << NS << "\n";
    }
    fin.close ();
    fout.close ();
    return 0;
}