Cod sursa(job #2202419)

Utilizator dahaandreiDaha Andrei Codrin dahaandrei Data 8 mai 2018 18:58:06
Problema Struti Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <deque>

using namespace std;

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

const int MAXNM = 1e3;

int n, m, p, d1, d2;
int mat[MAXNM + 2][MAXNM + 2];

int abs(int nr){
  if (nr < 0)
    return -nr;
  return nr;
}

pair <int, int> retMinMax(int dx, int dy){
  struct ceva{
    int val;
    int poz;

    ceva (int _val = 0, int _poz = 0){
      val = _val;
      poz = _poz;
    }
  }dq;

  deque <ceva>mindq[dy + 1];
  deque <ceva>maxdq[dy + 1];
  int minim, maxim;
  minim = 8001, maxim = 0;
  int minDif = abs(maxim - minim);
  int cnt = 0;

  for (int start = 1; start <= n - dy + 1; ++ start){
    for (int i = 0; i < dy + 1; ++ i)
      mindq[i].clear(), maxdq[i].clear();
    for (int i = 1; i <= dy; ++ i){
      for (int j = 1; j < dx; ++ j){
        dq.poz = j;
        dq.val = mat[start + i - 1][j];

        if (!mindq[i].empty())
          while (mindq[i].back().val >= dq.val){
            mindq[i].pop_back();
            if (mindq[i].empty())
              break;
          }
        mindq[i].push_back(dq);
        while (mindq[i].front().poz <= j - dx)
          mindq[i].pop_front();

        if (!maxdq[i].empty())
          while (maxdq[i].back().val <= dq.val){
            maxdq[i].pop_back();
            if (maxdq[i].empty())
              break;
          }
        maxdq[i].push_back(dq);
        while (maxdq[i].front().poz <= j - dx)
          maxdq[i].pop_front();
      }
    }

    for (int j = dx; j <= m; ++ j){
      int currMin = 8001, currMax = 0;
      for (int k = 1; k <= dy; ++ k){
        dq.poz = j;
        dq.val = mat[start + k - 1][j];

        if (!mindq[k].empty())
          while (mindq[k].back().val >= dq.val){
            mindq[k].pop_back();
            if (mindq[k].empty())
              break;
          }
        mindq[k].push_back(dq);
        while (mindq[k].front().poz <= j - dx)
          mindq[k].pop_front();

        if (!maxdq[k].empty())
          while (maxdq[k].back().val <= dq.val){
            maxdq[k].pop_back();
            if (maxdq[k].empty())
              break;
          }
        maxdq[k].push_back(dq);
        while (maxdq[k].front().poz <= j - dx)
          maxdq[k].pop_front();

        currMin = min(currMin, mindq[k].front().val);
        currMax = max(currMax, maxdq[k].front().val);
      }
      if (abs(currMax - currMin) < minDif){
        minDif = abs(currMax - currMin);
        minim = currMin;
        maxim = currMax;
        cnt  = 1;
      }
      else if (abs(currMax - currMin) == minDif)
        ++ cnt;
    }
  }

  return make_pair(abs(maxim - minim), cnt);
}

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

  for (int i = 1; i <= n; ++ i)
    for (int j = 1; j <= m; ++ j)
      in >> mat[i][j];

  while (p --){
    in >> d1 >> d2;

    pair <int, int>rez;
    rez = retMinMax(d1, d2);
    pair <int, int>aux;
    aux = retMinMax(d2, d1);

    if (rez.first < aux.first)
      out << rez.first << ' ' << rez.second << '\n';
    if (rez.first == aux.first)
      if (d1 != d2)
        out << rez.first << ' ' << rez.second + aux.second << '\n';
      else
        out << rez.first << ' ' << rez.second << '\n';
    if (rez.first > aux.first)
      out << aux.first << ' ' << aux.second << '\n';
  }

  return 0;
}