Cod sursa(job #1047249)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 4 decembrie 2013 08:48:38
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>
#include <deque>
#include <cstdlib>
using namespace std;
int n, m, P, mat[1010][1010], sol, nrsol;
deque <int> mincol[1010], maxcol[1010], minlin, maxlin;
char *buffer;

inline void Solve(int Dx, int Dy)
{
	int i, j, i1, i2, j1, j2;
	for(i = 1; i <= n; ++i)
	{
		for(j = 1; j <= m; ++j)
		{
			// actualizez minimul de pe coloana j din dreptunghi
			while(!mincol[j].empty() && mat[mincol[j].back()][j] >= mat[i][j])
				mincol[j].pop_back();
			mincol[j].push_back(i);
			while(mincol[j].front() <= i - Dx)
				mincol[j].pop_front();
			
			// actualizez maximul de pe coloana j din dreptunghi
			while(!maxcol[j].empty() && mat[maxcol[j].back()][j] <= mat[i][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 minimul din dreptunghiul curent
				while(!minlin.empty() && mat[mincol[minlin.back()].front()][minlin.back()] >= mat[i1][j])
					minlin.pop_back();
				minlin.push_back(j);
				while(minlin.front() <= j - Dy)
					minlin.pop_front();
				
				//actualizez maximul din dreptunghiul curent
				while(!maxlin.empty() && mat[maxcol[maxlin.back()].front()][maxlin.back()] <= mat[i2][j])
					maxlin.pop_back();
				maxlin.push_back(j);
				while(maxlin.front() <= j - Dy)
					maxlin.pop_front();
				
				// verific daca pot avea deja un dreptunghi de dimensiuni Dx, Dy
				if(j >= Dy)
				{
					// actualizez solutia
					j1 = minlin.front(); // coloana minimului
					i1 = mincol[j1].front(); // linia minimului
					j2 = maxlin.front(); // coloana maximului
					i2 = maxcol[j2].front(); // linia maximului
					if(sol > mat[i2][j2] - mat[i1][j1])
					{
						sol = mat[i2][j2] - mat[i1][j1];
						nrsol = 1;
					}
					else
						if(sol == mat[i2][j2] - mat[i1][j1])
							nrsol++;
				}
			}
		}
		minlin.clear();
		maxlin.clear();
	}
	for(j = 1; j <= m; ++j)
	{
		mincol[j].clear();
		maxcol[j].clear();
	}
}

inline void Citeste(int &x)
{
	while(*buffer < '0' || '9' < *buffer)
		buffer++;
	x = 0;
	while('0' <= *buffer && *buffer <= '9')
	{
		x = x * 10 + *buffer - '0';
		buffer++;
	}
}

int main()
{
	int i, j, Dx, Dy;
	
	ifstream fin("struti.in");
	fin.seekg(0, ios::end);
	int fs = fin.tellg();
	fin.seekg(0, ios::beg);
	buffer = (char *)malloc(fs);
	fin.getline(buffer, fs, 0);
	fin.close();
	
	ofstream fout("struti.out");
	Citeste(n); Citeste(m); Citeste(P);
	for(i = 1; i <= n; ++i)
		for(j = 1; j <= m; ++j)
			Citeste(mat[i][j]);
	for(i = 1; i <= P; ++i)
	{
		Citeste(Dx); Citeste(Dy);
		sol = 1000000000;
		nrsol = 0;
		Solve(Dx, Dy);
		if(Dx != Dy)
			Solve(Dy, Dx);
		fout << sol << " " << nrsol << "\n";
	}
	fout.close();
	return 0;
}