Cod sursa(job #623158)

Utilizator andra23Laura Draghici andra23 Data 19 octombrie 2011 12:59:21
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include<iostream>
#include<fstream>
#include<deque>

using namespace std;

const int MAXN = 1005;
int a[MAXN][MAXN];
deque <int> mind[MAXN], maxd[MAXN];
deque <int> mindiff, maxdiff;
int minOnColumn[MAXN], maxOnColumn[MAXN];

int calculateMaxDiff(int m, int n, int dx, int dy, int &minim) {
	minim = 8005;
	int num = 0;
	for (int i = 1; i <= n; i++) {
		mind[i].clear();
		maxd[i].clear();
	}

	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			while (!mind[j].empty() && a[i][j] < a[mind[j].back()][j]) {
				mind[j].pop_back();
			}
			mind[j].push_back(i);
			if (i - mind[j].front() + 1 > dy) {
				mind[j].pop_front();
			}
			minOnColumn[j] = a[mind[j].front()][j];

			while (!maxd[j].empty() && a[i][j] > a[maxd[j].back()][j]) {
				maxd[j].pop_back();
			}
			maxd[j].push_back(i);
			if (i - maxd[j].front() + 1 > dy) {
				maxd[j].pop_front();
			}
			maxOnColumn[j] = a[maxd[j].front()][j];
		}

		if (i >= dy) {
			mindiff.clear();
			maxdiff.clear();
			for (int j = 1; j <= n; j++) {
				while (!mindiff.empty() && minOnColumn[mindiff.back()] > 
						minOnColumn[j]) {
					mindiff.pop_back();
				}
				mindiff.push_back(j);
				if (j - mindiff.front() + 1 > dx) {
					mindiff.pop_front();
				}

				while (!maxdiff.empty() && maxOnColumn[maxdiff.back()] <
						maxOnColumn[j]) {
					maxdiff.pop_back();
				}
				maxdiff.push_back(j);
				if (j - maxdiff.front() + 1 > dx) {
					maxdiff.pop_front();
				}
				
				int x = maxOnColumn[maxdiff.front()] - minOnColumn[mindiff.front()];
				if (j >= dx) {
					if (x < minim) {
						minim = x;
						num = 1;
					} else if (minim == x) {
						num++;
					}
				}	
			}
		}
	}
	return num;
}

int main() {
	ifstream f("struti.in");
	ofstream g("struti.out");

	int m, n, p;
	f >> m >> n >> p;

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

	for (int i = 1; i <= p; i++) {
		int dx, dy;
		f >> dx >> dy;
		int num1, min1, num2, min2;
		num1 = calculateMaxDiff(m, n, dx, dy, min1);
		if (dx != dy) {
			num2 = calculateMaxDiff(m, n, dy, dx, min2);
			if (min2 < min1) {
				num1 = num2;
				min1 = min2;
			} else if (min2 == min1){
				num1 += num2;
			}
		}
		g << min1 << " " << num1 << '\n'; 
	}

	return 0;
}