Cod sursa(job #1081544)

Utilizator razvan9310FMI - Razvan Damachi razvan9310 Data 13 ianuarie 2014 18:36:31
Problema Struti Scor 0
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.91 kb
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;

void buildMatrix(int **mat, int **min_max_mat, deque<int> &deq, const int &M, const int &N,
								const int &x, const int &y, const bool &minim) {
	for (int i = 0; i < M; ++i) {
		//pe fiecare linie, voi baga intai primele x coloane in deque
		deq.clear();
		for (int j = 0; j < x; ++j) {
			deq.push_back(j);
			while (deq.size() > 0 && (minim ? mat[i][deq.front()] > mat[i][j] : mat[i][deq.front()] < mat[i][j])) {
				deq.pop_front();
			}
		}

		min_max_mat[i][x - 1] = mat[i][deq.front()];

		for (int j = x; j < N; ++j) {
			if (deq.front() <= j - x) {
				deq.pop_front();
			}
			deq.push_back(j);
			while (deq.size() > 0 && (minim ? mat[i][deq.front()] > mat[i][j] : mat[i][deq.front()] < mat[i][j])) {
				deq.pop_front();
			}

			min_max_mat[i][j] = mat[i][deq.front()];
		}
	}
}

void solve(int **mat, const int &M, const int &N, const int &x, const int &y,
					int &MIN, int &nro) {
	//matricea are M linii si N coloane;
	//subdreptunghiul are y linii si x coloane

	deque<int> min_deq, max_deq;

	int **min_mat = new int*[M];
	int **max_mat = new int*[M];
	for (int i = 0; i < M; ++i) {
		min_mat[i] = new int[N];
		max_mat[i] = new int[N];
		for (int j = 0; j < N; ++j) {
			min_mat[i][j] = 1 << 30;
			max_mat[i][j] = 0;
		}
	}

	buildMatrix(mat, min_mat, min_deq, M, N, x, y, 1);
	buildMatrix(mat, max_mat, max_deq, M, N, x, y, 0);

	int **diff_mat = new int*[M];
	for (int i = 0; i < M; ++i) {
		diff_mat[i] = new int[N];
		for (int j = 0; j < N; ++j) {
			diff_mat[i][j] = 1 << 30;
		}
	}

	for (int j = x - 1; j < N; ++j) {
		// pe fiecare coloana fac deque-urile
		min_deq.clear(), max_deq.clear();

		for (int i = 0; i < y; ++i) {
			min_deq.push_back(i);
			while (min_deq.size() > 0 && min_mat[min_deq.front()][j] > min_mat[i][j]) {
				min_deq.pop_front();
			}

			max_deq.push_back(i);
			while (max_deq.size() > 0 && max_mat[max_deq.front()][j] < max_mat[i][j]) {
				max_deq.pop_front();
			}
		}

		diff_mat[y - 1][j] = max_mat[max_deq.front()][j] - min_mat[min_deq.front()][j];

		for (int i = y; i < M; ++i) {
			if (min_deq.front() <= i - y) {
				min_deq.pop_front();
			}
			if (max_deq.front() <= i - y) {
				max_deq.pop_front();
			}

			min_deq.push_back(i);
			while (min_deq.size() > 0 && min_mat[min_deq.front()][j] > min_mat[i][j]) {
				min_deq.pop_front();
			}

			max_deq.push_back(i);
			while (max_deq.size() > 0 && max_mat[max_deq.front()][j] < max_mat[i][j]) {
				max_deq.pop_front();
			}

			diff_mat[i][j] = max_mat[max_deq.front()][j] - min_mat[min_deq.front()][j];
		}
	}

	for (int i = y - 1; i < M; ++i) {
		for (int j = x - 1; j < N; ++j) {
			if (diff_mat[i][j] < MIN) {
				MIN = diff_mat[i][j];
				nro = 1;
			} else {
				if (diff_mat[i][j] == MIN) {
					++nro;
				}
			}
		}
	}

	for (int i = 0; i < M; ++i) {
		delete[] min_mat[i];
		delete[] max_mat[i];
		delete[] diff_mat[i];
	}
	delete[] min_mat;
	delete[] max_mat;
	delete[] diff_mat;
}

int main() {
	int M, N, P;
	ifstream in("struti.in");
	in >> M >> N >> P;

	int **mat = new int*[M];
	for (int i = 0; i < M; ++i) {
		mat[i] = new int[N];
		for (int j = 0; j < N; ++j) {
			in >> mat[i][j];
		}
	}

	ofstream out("struti.out");

	for (int i = 0; i < P; ++i) {
		int x, y;
		in >> x >> y;
		int min1 = 1 << 30, min2 = 1 << 30, nro1 = 0, nro2 = 0;

		solve(mat, M, N, x, y, min1, nro1);
		solve(mat, M, N, y, x, min2, nro2);

		if (min1 < min2) {
			out << min1 << " " << nro1 << "\n";
		} else {
			if (min1 == min2) {
				if (x != y) {
					out << min1 << " " << nro1 + nro2 << "\n";
				} else {
					out << min1 << " " << nro1 << "\n";
				}
			} else {
				out << min2 << " " << nro2 << "\n";
			}
		}
	}

	in.close();
	out.close();

	for (int i = 0; i < M; ++i) {
		delete[] mat[i];
	}
	delete[] mat;

	return 0;
}