Cod sursa(job #1023826)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 7 noiembrie 2013 19:45:54
Problema Struti Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.69 kb
#include <fstream>
#include <deque>

#define maxn 1001
#define inf 1<<30

using namespace std;

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

int a[maxn][maxn];
int colmax[maxn][maxn],colmin[maxn][maxn],rowmax[maxn][maxn],rowmin[maxn][maxn];
int nr,val,n,m,p,x,y;

void mins_and_maxs (int x, int y)
{
    deque <int> mind,maxd;

    if (x!=y)
    for (int i=1; i<=n; ++i)
    {
        int j;
        for (j=1; j<y; ++j)
        {
            while (!mind.empty() && a[i][j] <= a[i][mind.back()]) mind.pop_back ();
            mind.push_back (j);

            while (!maxd.empty() && a[i][j] >= a[i][maxd.back()]) maxd.pop_back();
            maxd.push_back (j);
        }

        for (; j<=m; ++j)
        {
            while (!mind.empty() && a[i][j] <= a[i][mind.back()]) mind.pop_back ();
            mind.push_back (j);

            while (!maxd.empty() && a[i][j] >= a[i][maxd.back()]) maxd.pop_back();
            maxd.push_back (j);

            rowmin[i][j] = a[i][mind.front()];
            rowmax[i][j] = a[i][maxd.front()];

            if (mind.front() <= j-y+1) mind.pop_front();
            if (maxd.front() <= j-y+1) maxd.pop_front();
        }
        mind.clear(); maxd.clear();
    }

    for (int j=1; j<=m; ++j)
    {
        int i;
        for (i=1; i<x; ++i)
        {
            while (!mind.empty() && a[i][j] <= a[mind.back()][j]) mind.pop_back ();
            mind.push_back (i);

            while (!maxd.empty() && a[i][j] >= a[maxd.back()][j]) maxd.pop_back();
            maxd.push_back (i);
        }

        for (; i<=n; ++i)
        {
            while (!mind.empty() && a[i][j] <= a[mind.back()][j]) mind.pop_back ();
            mind.push_back (i);

            while (!maxd.empty() && a[i][j] >= a[maxd.back()][j]) maxd.pop_back();
            maxd.push_back (i);

            colmin[i][j] = a[mind.front()][j];
            colmax[i][j] = a[maxd.front()][j];

            if (mind.front() <= i-x+1) mind.pop_front();
            if (maxd.front() <= i-x+1) maxd.pop_front();
        }
        mind.clear(); maxd.clear();
    }
}

void compute (int x, int y)
{
    deque <int> mind,maxd;

    for (int i=x; i<=n; ++i)
    {
        int j;
        for (j=1; j<y; ++j)
        {
            while (!mind.empty() && colmin[i][j] <= colmin[i][mind.back()]) mind.pop_back ();
            mind.push_back (j);

            while (!maxd.empty() && colmax[i][j] >= colmax[i][maxd.back()]) maxd.pop_back();
            maxd.push_back (j);
        }

        for (; j<=m; ++j)
        {
            while (!mind.empty() && colmin[i][j] <= colmin[i][mind.back()]) mind.pop_back ();
            mind.push_back (j);

            while (!maxd.empty() && colmax[i][j] >= colmax[i][maxd.back()]) maxd.pop_back();
            maxd.push_back (j);

            int dif = colmax[i][maxd.front()] - colmin[i][mind.front()];

            if (dif < val)
            {
                val = dif;
                nr = 1;
            }
            else if (dif==val)
            {
                ++nr;
            }

            if (mind.front() <= j-y+1) mind.pop_front();
            if (maxd.front() <= j-y+1) maxd.pop_front();
        }

        mind.clear(); maxd.clear();
    }

    if (x!=y)
    for (int j=y; j<=m; ++j)
    {
        int i;
        for (i=1; i<x; ++i)
        {
            while (!mind.empty() && rowmin[i][j] <= rowmin[mind.back()][j]) mind.pop_back ();
            mind.push_back (i);

            while (!maxd.empty() && rowmax[i][j] >= rowmax[maxd.back()][j]) maxd.pop_back();
            maxd.push_back (i);
        }

        for (; i<=n; ++i)
        {
            while (!mind.empty() && rowmin[i][j] <= rowmin[mind.back()][j]) mind.pop_back ();
            mind.push_back (i);

            while (!maxd.empty() && rowmax[i][j] >= rowmax[maxd.back()][j]) maxd.pop_back();
            maxd.push_back (i);

            int dif = (rowmax[maxd.front()][j] - rowmin[mind.front()][j]);

            if (dif < val)
            {
                val = dif;
                nr = 1;
            }
            else if (dif==val)
            {
                nr++;
            }

            if (mind.front() <= i-x+1) mind.pop_front();
            if (maxd.front() <= i-x+1) maxd.pop_front();
        }
        mind.clear(); maxd.clear();
    }
}

int main()
{
    fin>>n>>m>>p;

    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
    {
        fin>>a[i][j];
    }

    for (int k=1; k<=p; ++k)
    {
        fin>>x>>y;

        mins_and_maxs(x,y);

        val = inf;
        nr = 0;

        compute (x,y);

        fout<<val<<" "<<nr<<"\n";
    }
}