Cod sursa(job #1061837)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 20 decembrie 2013 12:53:56
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <fstream>
#include <deque>
#define Lmax 1005
#define Lg 1000000
#define verf ++poz==Lg? fin.read(Buffer,Lg), poz=0:0

using namespace std;
ifstream fin("struti.in");

int L,C,a[Lmax][Lmax],poz,sol,nrsol;
char Buffer[Lg];
deque <int> mincol[Lmax],maxcol[Lmax],coloanamin,coloanamax;
/// mincol[j] - > liniile in ordine crescatoare cu inaltimea in ord crescatoare pt col j
/// maxcol[j] - > liniile in ordine crescatoare cu inaltimea in ord descrescatoare pt col j
/// coloanamin - >coloana in care se afla el minim din dr curent
/// coloanamax - >coloana pe care se afla elementul maxim din dr curent

inline void Citeste(int &x)
{
    for(; Buffer[poz]<'0' || Buffer[poz]>'9'; verf);
    for(x=0; Buffer[poz]>='0' && Buffer[poz]<='9'; x=x*10+Buffer[poz]-'0', verf);
}

inline void Solve(int DX, int DY)
{
    int i,j,i1,i2,j1,j2;
    for(i=1;i<=L;++i)
    {
        for(j=1;j<=C;++j)
        {
            /// actualizez pentru coloana j
            while(!mincol[j].empty() && a[i][j]<=a[mincol[j].back()][j])
                mincol[j].pop_back();
            mincol[j].push_back(i);
            while(mincol[j].front()<=i-DX)
                mincol[j].pop_front();

            while(!maxcol[j].empty() && a[i][j]>=a[maxcol[j].back()][j])
                maxcol[j].pop_back();
            maxcol[j].push_back(i);
            while(maxcol[j].front()<=i-DX)
                maxcol[j].pop_front();

            if(i>=DX)
            {
                i1 = mincol[j].front(); /// minimul de pe coloana curenta din dreptunghi
                i2 = maxcol[j].front(); /// maximul de pe coloana curenta din dreptunghi
                ///actualizez pentru dreptunghiul curent

                while(!coloanamin.empty() && a[i1][j]<=a[mincol[coloanamin.back()].front()][coloanamin.back()])
                    coloanamin.pop_back();
                coloanamin.push_back(j);
                while(coloanamin.front()<=j-DY)
                    coloanamin.pop_front();
                while(!coloanamax.empty() && a[i2][j]>=a[maxcol[coloanamax.back()].front()][coloanamax.back()])
                    coloanamax.pop_back();
                coloanamax.push_back(j);
                while(coloanamax.front()<=j-DY)
                    coloanamax.pop_front();
                if(j>=DY)
                {
                    j1=coloanamin.front();
                    i1=mincol[j1].front();
                    j2=coloanamax.front();
                    i2=maxcol[j2].front();
                    if(a[i2][j2]-a[i1][j1]<sol)
                    {
                        sol=a[i2][j2]-a[i1][j1];
                        nrsol=1;
                    }
                    else
                        if(a[i2][j2]-a[i1][j1]==sol)
                            ++nrsol;
                }
            }
        }
        coloanamax.clear();
        coloanamin.clear();
    }
    for(i=1;i<=C;++i)
    {
        mincol[i].clear();
        maxcol[i].clear();
    }
}

int main()
{
    int i,j,P,DX,DY;
    ofstream fout("struti.out");
    Citeste(L); Citeste(C); Citeste(P);
    for(i=1;i<=L;++i)
        for(j=1;j<=C;++j)
            Citeste(a[i][j]);
    while(P--)
    {
        Citeste(DX); Citeste(DY);
        sol=1000000000; nrsol=0;
        Solve(DX,DY);
        if(DX!=DY)
            Solve(DY,DX);
        fout<<sol<<" "<<nrsol<<"\n";
    }
    fin.close();
    fout.close();
    return 0;
}